【问题标题】:malloc and realloc segmentation faultmalloc 和 realloc 分段错误
【发布时间】:2015-01-20 07:03:02
【问题描述】:

我正在使用 linux 并用作编译器 gcc。 我对函数 malloc 和 realloc 做了一些经验,试图了解它是如何工作的。但是当我执行程序时给我分段错误。 接下来是我的代码:

#include<stdio.h>
#include<stdlib.h>

 int main(){
  register int cont=1;
  int i,n,*a;
  a=(int*)malloc(sizeof(int));
  scanf("%d",&n);
  while(n!=0){
   if(a!=NULL)
    a=(int*)realloc(a,cont*sizeof(int));
   else 
    goto exit;
   a[i]=n;
   scanf("%d",&n);
   cont++;
   i++;
 }

 for(i=0;i<cont;i++)
  printf("%d\n",a[i]);
 free(a);
 return 0;

 exit: printf("No memory\n");
 free(a);
 return -1;



}

为什么这不起作用以及我的代码有什么问题?

【问题讨论】:

  • 使用这个 GCC 命令行:gcc -Wall -Werror -g main.c 这将启用警告,并在您的可执行文件中包含调试信息。然后使用gdb a.out 在调试器中运行您的代码。键入c 以“继续”。然后它会准确指出您的程序崩溃的位置。
  • 您是否尝试过使用调试器?什么时候出现错误?
  • 你从未初始化过i
  • 请注意,当您使用realloc() 时,如a = (int*)realloc(a, cont * sizeof(int)); 所示,如果重新分配失败,您将面临内存泄漏的风险。那是因为当它失败时,它会用 NULL 覆盖a,这意味着你已经丢失了指向内存的旧指针。始终使用int *new_a = (int *)realloc(a, cont * sizeof(int)); if (new_a != 0) a = new_a;,以便在出现问题时仍然可以释放先前分配的内存。这段代码无关紧要。一般来说,它确实很重要。通常最好在标准错误流上报告错误,并避免使用goto

标签: c pointers memory-management


【解决方案1】:

i 从未初始化,因此a[i]=n; 可能会导致分段错误。将其更改为:

int i = 0;

您的代码还可以进行一些其他改进,例如don't cast the result of malloc,在我看来,您使用goto 看起来没有必要,而register 关键字可能没用。

【讨论】:

  • 非常感谢;但是现在输入:2 3 4 5 6 7 8 0 结果输出:2 3 4 5 6 7 8 135137 知道这个 135137 是什么吗?
【解决方案2】:

在while循环中,用户输入0后,它被存储在n中,你增加了cont,当while循环再次检查进入条件n != 0它失败了(因为现在n的值为 0) 并退出循环而不将 n 值存储到 a,这就是为什么您在输出的最后一个位置得到不确定值的原因。

当您使用 realloc 时,您不应将返回值直接存储到您试图增加大小的指针变量中,因为 realloc 在失败时返回 NULL,您最终会将句柄/地址擦除到内存缓冲区。

    register int cont = 1;
    int i = 0,n,*a;
    int *temp;
    a = (int*)malloc(sizeof(int));
    if(a == NULL) goto exit;
    while(1){
       scanf("%d", &n);
       temp = (int*)realloc(a, cont * sizeof(int));
       if(temp == NULL)
         goto exit;
       else
         a = temp;
       a[i++] = n;
       if(n == 0) // put the condition here if u want to store 0
         break;  
       else
         cont++;
     }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-28
    • 2014-09-22
    • 2014-03-29
    • 2011-04-22
    • 1970-01-01
    相关资源
    最近更新 更多