【 C 】动态内存分配案例分析

版权声明:本博客内容来自于个人学习过程中的总结,参考了互联网以及书本、论文等上的内容,仅供学习交流使用,如有侵权,请联系我会重写!转载请注明地址! https://blog.csdn.net/Reborn_Lee/article/details/82622485

声明一个指向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.” 的首地址。

但是下面的这种情况是不允许的,就是对该指针进行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这个函数掌握的不够了。

我专门写一篇博文来记录这个问题吧,毕竟是自己踩过的坑!我相信也会有人会有此疑惑,但如果接着写的话,恐怕就不能够直接搜索到这个知识点了。

【 C 】关于学习 realloc 踩过的那些坑

给个别人的博文参考地址:http://www.cnblogs.com/hnrainll/archive/2011/07/27/2118812.html

最后推荐一篇博文,以后我也会仔细看看:

https://blog.csdn.net/sendfeng/article/details/6215016

猜你喜欢

转载自blog.csdn.net/Reborn_Lee/article/details/82622485