c - 该代码在 gcc 编译器上正常工作,但是当我将其提交到编码门户(SPOJ)时,它显示运行时错误,为什么?

标签 c pointers segmentation-fault runtime-error realloc

#include<stdio.h>
#include<stdlib.h>
int main()
{
   int *p=(int*)malloc(10*4);
   int i,a,count=1;
   printf("Input :\n");
   for(i=0;i<10*count;i++)
   {
     scanf("%d",p+i);
     if(*(p+i)==22){
         break;
        }
     if(i==9+(count-1)*10){
          realloc(p,(10+10*count)*sizeof(int));
          count++;
       }
    }
    printf("\nOutput :\n");
    i=0;
    for(;;){
        if(*(p+i)==22){
           break;
        }
        printf("%d\n",*(p+i));
        i++;
     }
}

代码的目的是连续获取输入,直到遇到 22,当遇到 22 时,它会打印我在它之前输入的所有值 SPOJ 在 Ideone.com 上运行代码

最佳答案

天哪,我太慢了。

*** Error in `./prog': realloc(): invalid old size: 0x09654008 ***

以下是最可能出现的问题:

  1. 第一个之后 malloc调用,p设置为某个堆地址(我们称之为 0x1000 );
  2. 第一个realloc无法调整当前位置的缓冲区大小,因此它在不同的地址分配一个缓冲区(称为 0x2000 )并将缓冲区标记为从 0x1000 开始可供使用;
  3. 您没有更新p指向这个新的缓冲区;
  4. 某些东西会覆盖从 0x1000 开始的内存,破坏存储的有关缓冲区大小的任何元数据;
  5. 您调用realloc再次,但自从 p仍然是0x1000 , realloc尝试调整先前释放的缓冲区的大小,该缓冲区已被覆盖;
  6. 无论您的元数据是什么 malloc使用的实现已被旧缓冲区覆盖,因此出现错误。

您需要保存从 realloc 返回的值,因为它可能与 p 不同(如果无法满足请求,则包括NULL):

int *tmp = realloc( p, sizeof *p * ( 10 + 10 * count ) );
if ( tmp )
  p = tmp;
else
  // realloc failed, handle as appropriate

您必须确保ptmp是同一类型。

此外,更改您的首字母 malloc调用

int *p = malloc( sizeof *p * 10 );

转换 malloc 的结果和realloc在 C1 中不鼓励,并且 sizeof *p给出与 sizeof (int) 相同的结果,如果您更改 p 的类型,还有一个额外的好处(从 int *long * )您不必将参数更改为 mallocrealloc -sizeof *p总会给你正确的答案。

<小时/> 1.是的,在 C++ 中,您必须转换 malloc 的结果,但如果您正在编写 C++,您就不会使用 malloc首先(对于本练习,您只需使用 std::vector<int> ,它可以根据需要增长)。

关于c - 该代码在 gcc 编译器上正常工作,但是当我将其提交到编码门户(SPOJ)时,它显示运行时错误,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33098520/

相关文章:

c - 将浮点值存储在 uint32_t 指针中

c - 二进制文件上 objdump 输出左侧的地址是什么?

c - 尝试在结构上使用scanf时出现段错误

segmentation-fault - 如何在cygwin中使用 "*.stackdump"文件进行调试

Lemon 中 token 析构函数的自定义释放函数

arrays - 为什么 C 中的指针可以在不取消引用的情况下打印其内容?

c++ - 使用 CPP 获取成员函数的地址

c - C语言中的指针(代码解释)

c++ - C++中没有指针的循环引用

c - 将指针分配给结构 C 时出现段错误