为什么这个程序崩溃了?

时间:2015-10-11 09:33:45

标签: c pointers malloc

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

int main()
{
    int i = 0, j = 0;
    int *p = (int *)malloc(1*4);
    for(;;)
    {
        scanf("%d", p+i);
        if(*(p+i) == 42)
        {
            break;
        }
        i++;
    }
    for(j = 0; j < i; j++)
    {
        printf("%dn", j);
    }
}

因为我知道我只创建了一个4字节的块,但是因为我们得到了p中存储的基址,所以我可以根据需要在循环中探索地址,即我会存储连续存储器位置的值,直到遇到42,问题是程序在5个输入端正常工作,但如果输入超过5个,程序就会崩溃。

我发现这个解决方案是由Alex Lop定义的Undefined行为但是我想知道为什么会这样做????

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int i=0,j=0;
    int *p=(int *)malloc(1*4);
    for(i=0;i<20;i++)
    {
        printf("%d\n",p+i);
    }
}

这里打印分配的内存串外的地址不会崩溃,最后打印出我没有分配的地址。

3 个答案:

答案 0 :(得分:3)

你实际上做的是“未定义的行为”。

您分配4个字节,然后存储到该缓冲区整数中。它对于第一个整数(或者如果你的机器上有sizeof(int)==2可能两个)工作正常但是对于下一个整数,行为变得不确定。它可能会立即发生段错误,直到您崩溃可能需要更多类似的商店。这里输入“5”的数量并不意味着什么,它在不同的机器上可能表现不同,并且具有不同的编译标记。

根据我所看到的(或从代码中假设),您希望接受输入,直到获得“42”。所以实际上你不必存储输入值。这是你的代码,没有无用的东西:

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

int main()
{
    int in;

    for(;;)
    {
        scanf("%d",&in);
        printf("%d\n", in); // adding this line because it was explained to
                            // me that the input values should be printed and 
                            //it is something I couldn't understand from the original code.
        if(in == 42)
        {
            break;
        }
    }

    return 0;
}

答案 1 :(得分:0)

您需要重新分配动态数组p才能存储所有值(i值)。在你的代码中,你只有一个整数(1 * 4)的空间。

试试这个:

#include<stdio.h>
#include<stdlib.h>
int main() {
    int i=0,j=0;
    int *p=(int *)malloc(1*sizeof(int)); //You can use sizeof(int) instead of 4
    for(;;) {
        p = realloc(p, (i+1)*sizeof(int)); //p can now store i integers
        scanf("%d",p+i);
        if(*(p+i)==42) { 
            break;
        }
        i++;
    }
    for(j=0;j<i;j++) {
        printf("%d\n",j);
    }
}

答案 2 :(得分:0)

我不知道从哪里开始。你甚至在哪里想到自己这样做?

首先,您必须指定要在sizeof(int)的块中进行分配。因为实际值可能会因不同的实现而改变(即使它通常为4)。

你的程序运行不正常。您无法根据需要浏览地址,因为您遇到了未定义的行为。您已经分配了4个字节,但正在访问超出您已分配内存的内存。崩溃所需的迭代次数(可能是1或2,或100)并不重要,这只是错误。