2017-10-01 29 views
-5

我有这种事:分段故障而使用malloc和采取输入

int n,m; 
scanf("%d %d",&m,&n); 
int *arr = malloc(sizeof(int)*n*m); 
for(int i=0;i<m*n;scanf("%d",arr+i),i++); 

现在对于比如说N = 2和M = 3,它接受的第一个五年号码,并提供了有关分段错误第六个数字。我在循环之后立即尝试打印内容,但没有打印,不知道问题可能是什么?我广泛使用了类似的构造,从未遇到过问题。

编辑1: 该问题后来在程序中,但事情是我在循环后立即有一个printf,并没有打印任何东西,所以我认为它必须在这里。为什么printf没有打印什么?它与平行执行有关吗?对于坏格式抱歉,我是堆栈溢出新手。

+1

阅读有关[未定义行为(https://en.wikipedia.org/wiki/Undefined_behavior)和[缓冲区溢出(HTTPS的另一种方式:// EN .wikipedia.org /维基/ Buffer_overflow)。编译所有警告和调试信息('gcc -Wall -Wextra -g')。 **使用调试器**'gdb'和[valgrind](http://valgrind.org/)。下次你在SO上提出一些问题时,请给出一些[MCVE](http://stackoverflow.com/help/mcve)。这*修复我的代码*问题是脱离主题。另请阅读[文档](http://en.cppreference.com/w/c),特别是'malloc'和'scanf' –

+6

“这类东西”....请研究[mcve] 。 – Yunnosch

+0

在调试器中检查'm','n','arr'的值(在'for'循环中有断点)。我相信你会感到惊讶。 –

回答

1

试试这个,

int n,m; 
printf("Enter two digits"); 
int scanCount = scanf("%d %d", &m, &n); 
if(scanCount < 2){ 
    perror("Input"); 
    exit(EXIT_FAILURE); 
} 
scanCount = 0; 
size_t size = sizeof(int) * n * m; 
int * arr = (int *) malloc(size); 
if (arr == NULL) { 
    perror("malloc"); 
    exit(EXIT_FAILURE); 
}; 
for(int i = 0; i < m * n; i++){ 
    if (scanf("%d", arr + i)) 
     scanCount++; 
} 
if(scanCount < m*n){ 
    perror("Input"); 
    exit(EXIT_FAILURE); 
} 
for(int i=0; i<n*m; i++){ 
    printf("\nValue at %d : %d\n", i, *(arr + i)); 
} 

我已经修改了上面给出的程序一点点,而现在它为我工作。 的malloc函数期望“的std ::的size_t大小”(我们也可以提供整数值)作为参数,这是我们需要分配存储器的大小。请访问http://en.cppreference.com/w/cpp/memory/c/malloc以供参考。

此外,我们应该指定我们正在创建的存储器的类型(否则它可能在一些编译器产生的误差,这样“从‘无效*’到‘INT *’无效转换”)。在这种情况下,我们creting整数的数组,我们可以使用类型cating,例如 为(int *)malloc的(尺寸)。

最好是通过scanf实施失败的内存分配和投入一些错误处理程序(检查malloc和scanf函数的返回值)

+3

缺少对'malloc'失败的检查:if(arr == NULL){perror(“malloc”); exit(EXIT_FAILURE);};'和'malloc'无用的强制转换; BTW'scanf'也可能失败,你的代码不检查。回答**以加以改进 –

+0

@BasileStarynkevitch我应该在scanf的情况下检查什么? – HariV

+0

了解更多关于[scanf](http://en.cppreference.com/w/c/io/fscanf)的信息。计数哪些应该被测试......有时'%n'也是有帮助的 –

1

我试图运行程序here。没有错误。也许这是巧合,只是碰巧运行,但也许你在打印循环内的值时出错,如this

如果是这样,那是因为最后一次迭代过程中尝试编写没有被分配到使用malloc()的记忆的一部分。类似于arr[6],直到arr[5]实际上在n = 2和m = 3时被分配。这样做会调用未定义的行为。看看评论中指出的链接@Basil

您必须检查由malloc()回来发现,如果内存分配成功的价值。如果失败,则返回NULL

而且scanf()的返回值可以被检查发现,如果它是成功还是失败。它返回循环中scanf()必须为1的成功分配数。如果它不是1发生了一些错误。

这是编写循环

for(i=0;i<m*n && scanf("%d", arr+i)==1;i++);