【 C 】动态内存分配案例分析
声明一个指向char类型的指针,可以在声明的时候就对其进行初始化,这样是合理的。
例如:
E1:
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <string.h>
-
-
int main()
-
{
-
char name[100];
-
char *description = "Zara ali a DSP student in class 10th.";
-
-
strcpy(name, "Zara Ali");
-
-
printf("Name = %s\n", name );
-
printf("Description: %s\n", description );
-
}
运行结果:
-
$gcc -o main *.c
-
$main
-
Name = Zara Ali
-
Description: Zara ali a DSP student in class 10th.
这时,该指针description指向这个字符串 “Zara ali a DSP student in class 10th.” 的首地址。
实际上, “Zara ali a DSP student in class 10th.”是一个字符串常量,它作为表达式代表的是一个指针常量,指向第一个字符。所以,将该指针常量赋值给一个指针是很合理的,并且该指针指向该字符串的第一个字符元素。
有关字符串常量的博文:字符串常量,非常精彩!
但是下面的这种情况是不允许的,就是对该指针进行strcpy操作:
E2:
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <string.h>
-
-
int main()
-
{
-
char name[100];
-
char *description;
-
-
strcpy(name, "Zara Ali");
-
strcpy(description, "Zara ali a DSP student in class 10th...");
-
printf("Name = %s\n", name );
-
printf("Description: %s\n", description );
-
}
运行结果:
-
$gcc -o main *.c
-
$main
-
timeout: the monitored command dumped core
-
sh: line 1: 135176 Segmentation fault timeout 10s main
是什么原因呢?可以确定,是没有为description指向的地址开辟一块内存存放后面的字符串。
这条指针声明语句:
char *description;
只是声明了一个指向char类型的指针,并没有为其分配内存空间,它不像数组的声明一样,声明的同时直接开辟了规定的内存空间,例如:
char name[100];
这条语句在编译时,就分配了 100 * sizeof( char )个字节的内存。
下面的例子是使用动态内存分配的相关函数分配了内存之后的操作,畅通无阻:
E3:
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <string.h>
-
-
int main()
-
{
-
char name[100];
-
char *description;
-
-
strcpy(name, "Zara Ali");
-
-
/* 动态分配内存 */
-
description = (char *)malloc( 200 * sizeof(char) );
-
if( description == NULL )
-
{
-
fprintf(stderr, "Error - unable to allocate required memory\n");
-
}
-
else
-
{
-
strcpy( description, "Zara ali a DPS student in class 10th");
-
}
-
printf("Name = %s\n", name );
-
printf("Description: %s\n", description );
-
}
-
运行结果:
-
$gcc -o main *.c
-
$main
-
Name = Zara Ali
-
Description: Zara ali a DPS student in class 10th
我写博客用的是线上写代码,这样比较方便,不用还打开软件创建一个工程等等步骤,直接写代码之后运行,分析符不符合我的想法,随时修改,十分方便:Online C Compiler!
同样,上面这个例子中,必须对description这个指向字符的指针进行动态内存分配才能对其进行strcpy(字符串复制操作)操作,它不像你声明了一个数组一样,声明一个数组,会对其分配一定的内存,例如:
char name[100];
这条语句在编译时,就分配了 100 * sizeof( char )个字节的内存。
所以之后就不必担心内存有无的问题了,唯一值得担心的问题就是这里的内存够不够用,如果你确信够用,可以这么声明。但是,如果您预先不知道需要存储的文本长度,例如您向存储有关一个主题的详细描述。在这里,我们需要定义一个指针,该指针指向未定义所需内存大小的字符,后续再根据需求来分配内存,上例就是这么个用法。
当动态分配内存时,您有完全控制权,可以传递任何大小的值。而那些预先定义了大小的数组,一旦定义则无法改变大小。
上面的程序也可以使用 calloc() 来编写,只需要把 malloc 替换为 calloc 即可,如下所示:
calloc(200, sizeof(char));
重新调整内存的大小,使用realloc函数。
为什么要调整内存大小,是为了应付那些当时分配的内存大小不够用的情况,例子上面的例子,给description指针指向的地址分配了30 * sizeof( char ) 个字节的空间,然后进行如下操作:
E4:
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <string.h>
-
-
int main()
-
{
-
char name[100];
-
char *description;
-
-
strcpy(name, "Zara Ali");
-
-
/* 动态分配内存 */
-
description = (char *)malloc( 30 * sizeof(char) );
-
if( description == NULL )
-
{
-
fprintf(stderr, "Error - unable to allocate required memory\n");
-
}
-
else
-
{
-
strcpy( description, "Zara ali a DPS student.");
-
}
-
-
strcat( description, "She is in class 10th");
-
-
-
printf("Name = %s\n", name );
-
printf("Description: %s\n", description );
-
-
/* 使用 free() 函数释放内存 */
-
free(description);
-
}
运行结果:
出现错误,那是因为之前定义的内存不够用了,这个时候你应该增加内存之后,在进行字符串拼接(strcat)操作。
这里,我必须用电脑上安装的codeblock才会出现这种提示,如果用线上的编辑器,显示的结果是这样的:
-
$gcc -o main *.c
-
$main
-
Name = Zara Ali
-
Description: Zara ali a DPS student.She is in class 1
也看出来是没有显示完全,但是这个结果并不如意!可见,线上的编辑器我们简单的谢谢博客用用即可,毕竟没有主流的软件强大!
下面是一个修正后的例子:
E5:
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <string.h>
-
-
int main()
-
{
-
char name[100];
-
char *description;
-
-
strcpy(name, "Zara Ali");
-
-
/* 动态分配内存 */
-
description = (char *)malloc( 30 * sizeof(char) );
-
if( description == NULL )
-
{
-
fprintf(stderr, "Error - unable to allocate required memory\n");
-
}
-
else
-
{
-
strcpy( description, "Zara ali a DPS student.");
-
}
-
/* 假设您想要存储更大的描述信息 */
-
description = realloc( description, 100 * sizeof(char) );
-
if( description == NULL )
-
{
-
fprintf(stderr, "Error - unable to allocate required memory\n");
-
}
-
else
-
{
-
strcat( description, "She is in class 10th");
-
}
-
-
printf("Name = %s\n", name );
-
printf("Description: %s\n", description );
-
-
/* 使用 free() 函数释放内存 */
-
free(description);
-
}
-
运行结果:
-
$gcc -o main *.c
-
$main
-
Name = Zara Ali
-
Description: Zara ali a DPS student.She is in class 10th
最后补充一个malloc以及realloc使用的经典案例:
-
#include <stdio.h>
-
#include <stdlib.h>
-
-
int main () {
-
char *str;
-
-
/* Initial memory allocation */
-
str = (char *) malloc(15);
-
strcpy(str, "tutorialspoint");
-
printf("String = %s, Address = %u\n", str, str);
-
-
/* Reallocating memory */
-
str = (char *) realloc(str, 25);
-
strcat(str, ".com");
-
printf("String = %s, Address = %u\n", str, str);
-
-
free(str);
-
-
return(0);
-
}
在Code:Blockz中运行结果为:
String = tutorialspoint, Address = 2960224
String = tutorialspoint.com, Address = 2952960
Process returned 0 (0x0) execution time : 0.930 s
Press any key to continue.
初次见这个运行结果时候,前面的部分我还能接受,但仔细看了地址后,大吃一惊。(还是菜呀!哈哈哈),有些人可能会问,为什么地址不一样了,realloc不是在原内存的基础上添加了一块吗?所以最后返回的指针应该不变呀。这就是对realloc这个函数掌握的不够了。
我专门写一篇博文来记录这个问题吧,毕竟是自己踩过的坑!我相信也会有人会有此疑惑,但如果接着写的话,恐怕就不能够直接搜索到这个知识点了。
给个别人的博文参考地址:http://www.cnblogs.com/hnrainll/archive/2011/07/27/2118812.html
最后推荐一篇博文,以后我也会仔细看看:
https://blog.csdn.net/sendfeng/article/details/6215016
文章来源: reborn.blog.csdn.net,作者:李锐博恩,版权归原作者所有,如需转载,请联系作者。
原文链接:reborn.blog.csdn.net/article/details/82622485
- 点赞
- 收藏
- 关注作者
评论(0)