一步一步写算法(关于malloc函数)
2017-10-22 22:16
260 查看
v 接着上一次的自我实现字符串拷贝函数,其实我们在刚开始的main函数中也可以将char
a[10] = {0};char b[10] = {0};定义为两个指针char *a,*b;指针是指向地址的,同样应该可以用于my_copy(a,b);这个函数里面的地址传递。那么,我们来试一下,可不可以将char
a[10] = {0};char b[10] = {0};直接换为char *a,*b;来实现我们的字符串拷贝函数呢?
下面是进行尝试的函数:
#include <stdio.h>
void my_copy(char *i,char *j)
{
while(*i++ = *j++); //简练:同时实现取值,赋值,地址加一,三个功能
}
int main()
{
//char a[10] = {0};
//char b[10] = {0};
char *a,*b;
printf("Please input the string of b:\n");
scanf("%s",b);
my_copy(a,b);
printf("a : %s\n",a);
return 0;
}
运行结果:
在gcc编译环境下,在输入字符串后,终端上报出了段错误。
这是上面原因呢?
首先,段错误发生错误的原因是访问不该访问的内存空间。那么,也就是我们上述的程序中,有变量访问了不该访问的内存空间。
而我们刚刚只是修改了一下
char *a,*b;问题是出在这两个变量上。就变量所占的内存空间,我们来分析一下。其中,char *a,*b;中a,b变量只是指向地址,却没有确定的指向方向。这样操作是不合法的,因为在操作系统分配的虚拟内存当中,有些内存空间是我们开发人员无法进行操作的。所以,以上的地址指向不明,因而造成了段错误。(关于内存空间,我下面将另外用一篇博客来说明)
v 为了获得一段合理的内存,我们使用malloc函数。malloc函数的作用是在堆上开辟一段内存。虚拟内存中的堆的特点是:其空间由开发人员管理,空间的开辟和释放也是由开发人员完成。所以,我们可以通过malloc函数来为a,b变量在堆上开辟一段空间。
v 下面是单独写的一个函数来实现的为a,b变量在堆上开辟一段空间
v 程序示例:
#include <stdio.h>
#include <stdlib.h>
void my_copy(char *i,char *j)
{
while(*i++ = *j++);
}
void *memory_init(char *p)
{
p = (char *)malloc(sizeof(char)*10);
}
int main()
{
char *a,*b;
memory_init(a);
memory_init(b);
printf("Please input the string of b:\n");
scanf("%s",b);
my_copy(a,b);
printf("a : %s\n",a);
return 0;
}
运行结果:
当我们在输入字符串后,终端上又显示了段错误。
这是为什么呢?我们不是已经利用malloc函数为两个变量在堆上开辟了空间。为什么还是显示段错误呢?
v 下面我们利用例子来讲一下原因:假设原来指针变量a指向的空间是0x100,指针变量b指向的空间是0x200。在调用函数memory_init(a);函数后,a传地址0x100给p,然后利用malloc函数为p在堆上开辟了一段空间,假设在堆上开辟的空间首地址是0x500。但是在函数执行完后,形参P将释放空间,那么p里面保存的0x500也将会释放。最后,也就是相当于a的地址还是0x100,我们想要实现的为a开辟空间并没有实现。
v 如果想要解决这个问题,可以使用一个return
语句,来返回我们在堆上所开辟空间的地址。
v 程序示例:
#include <stdio.h>
#include <stdlib.h>
void my_copy(char *i,char *j)
{
while(*i++ = *j++);
}
char *memory_init()
{
return (char *)malloc(sizeof(char)*10);
}
int main()
{
char *a,*b;
a = memory_init();
b = memory_init();
printf("Please input the string of b:\n");
scanf("%s",b);
my_copy(a,b);
printf("a : %s\n",a);
return 0;
}
运行结果:
Please input the string of b:
hello
a : hello
由此,运行结果正确。
a[10] = {0};char b[10] = {0};定义为两个指针char *a,*b;指针是指向地址的,同样应该可以用于my_copy(a,b);这个函数里面的地址传递。那么,我们来试一下,可不可以将char
a[10] = {0};char b[10] = {0};直接换为char *a,*b;来实现我们的字符串拷贝函数呢?
下面是进行尝试的函数:
#include <stdio.h>
void my_copy(char *i,char *j)
{
while(*i++ = *j++); //简练:同时实现取值,赋值,地址加一,三个功能
}
int main()
{
//char a[10] = {0};
//char b[10] = {0};
char *a,*b;
printf("Please input the string of b:\n");
scanf("%s",b);
my_copy(a,b);
printf("a : %s\n",a);
return 0;
}
运行结果:
在gcc编译环境下,在输入字符串后,终端上报出了段错误。
这是上面原因呢?
首先,段错误发生错误的原因是访问不该访问的内存空间。那么,也就是我们上述的程序中,有变量访问了不该访问的内存空间。
而我们刚刚只是修改了一下
char *a,*b;问题是出在这两个变量上。就变量所占的内存空间,我们来分析一下。其中,char *a,*b;中a,b变量只是指向地址,却没有确定的指向方向。这样操作是不合法的,因为在操作系统分配的虚拟内存当中,有些内存空间是我们开发人员无法进行操作的。所以,以上的地址指向不明,因而造成了段错误。(关于内存空间,我下面将另外用一篇博客来说明)
v 为了获得一段合理的内存,我们使用malloc函数。malloc函数的作用是在堆上开辟一段内存。虚拟内存中的堆的特点是:其空间由开发人员管理,空间的开辟和释放也是由开发人员完成。所以,我们可以通过malloc函数来为a,b变量在堆上开辟一段空间。
v 下面是单独写的一个函数来实现的为a,b变量在堆上开辟一段空间
v 程序示例:
#include <stdio.h>
#include <stdlib.h>
void my_copy(char *i,char *j)
{
while(*i++ = *j++);
}
void *memory_init(char *p)
{
p = (char *)malloc(sizeof(char)*10);
}
int main()
{
char *a,*b;
memory_init(a);
memory_init(b);
printf("Please input the string of b:\n");
scanf("%s",b);
my_copy(a,b);
printf("a : %s\n",a);
return 0;
}
运行结果:
当我们在输入字符串后,终端上又显示了段错误。
这是为什么呢?我们不是已经利用malloc函数为两个变量在堆上开辟了空间。为什么还是显示段错误呢?
v 下面我们利用例子来讲一下原因:假设原来指针变量a指向的空间是0x100,指针变量b指向的空间是0x200。在调用函数memory_init(a);函数后,a传地址0x100给p,然后利用malloc函数为p在堆上开辟了一段空间,假设在堆上开辟的空间首地址是0x500。但是在函数执行完后,形参P将释放空间,那么p里面保存的0x500也将会释放。最后,也就是相当于a的地址还是0x100,我们想要实现的为a开辟空间并没有实现。
v 如果想要解决这个问题,可以使用一个return
语句,来返回我们在堆上所开辟空间的地址。
v 程序示例:
#include <stdio.h>
#include <stdlib.h>
void my_copy(char *i,char *j)
{
while(*i++ = *j++);
}
char *memory_init()
{
return (char *)malloc(sizeof(char)*10);
}
int main()
{
char *a,*b;
a = memory_init();
b = memory_init();
printf("Please input the string of b:\n");
scanf("%s",b);
my_copy(a,b);
printf("a : %s\n",a);
return 0;
}
运行结果:
Please input the string of b:
hello
a : hello
由此,运行结果正确。
相关文章推荐
- 关于路径搜索的算法, 可能用到
- 关于完美洗牌算法中圈和圈起点的一个证明
- 关于时间安排贪心算法正确性的证明
- 关于独立按键扫描程序的思考(整合两种算法)
- java 算法关于冒泡法的3种排序(优化)
- JAVA中关于链表的操作和基本算法
- 关于DNS转发时地址选择算法的问题
- 关于大整数的乘法的算法时间复杂度的计算过程推导(纯属个人推测,请高人指正)
- 关于算法的一点思考。。。
- 关于两个字符串的kmp比对算法
- 关于傻子坐飞机问题的答案 (算法的改进)
- 一步一步写算法(之 算法总结)
- 一步一步写算法(之 A*算法)
- 关于Yuri Boykov and Vladimir Kolmogorov 于2004年提出的max flow / min cut的算法的详解
- 一步一步写算法(之合并排序)
- 一步一步写算法(之线性堆栈)
- 一步一步写算法(之单词统计)
- 一步一步写算法(之图创建)
- 一步一步写算法(之哈夫曼树 上)
- [安全] 关于 RSA 算法的原理与实践