您的位置:首页 > 编程语言 > C语言/C++

一步一步写算法(关于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

 

由此,运行结果正确。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息