这个简单的C代码有什么问题?

时间:2012-03-03 02:51:59

标签: c memory-leaks error-handling

#include <stdio.h>

int main()
{
    int m,n; scanf("%d %d",&m,&n);
    char ar[m][n];
    char buf[n];
    int a,b;
    for(a=0;a<m;a++)
    {
        gets(buf);
        for(b=0;b<n;b++) ar[a][b] = buf[b];
    }
    for(a=0;a<m;a++,printf("\n")) for(b=0;b<n;b++) printf("%c",ar[a][b]);
    return 0;
}

此代码将 m 行作为stdin的输入,每行包含 n 个字符,并将所有行打印到stdout。就那么简单。但似乎存在内存泄漏,因为遇到第一次gets(buf)时,会跳过它的执行。

我也在C ++中尝试过,认为内存泄漏会消失。这是代码:

#include <cstdio>
using namespace std;

int main()
{
    int m,n; scanf("%d %d",&m,&n);
    char **ar = new char*[m];
    char *buf = new char[n];
    int a,b;
    for(a=0;a<m;a++)
    {
        gets(buf);
        ar[a] = new char[n];
        for(b=0;b<n;b++) ar[a][b] = buf[b];
    }
    for(a=0;a<m;a++,printf("\n")) for(b=0;b<n;b++) printf("%c",ar[a][b]);
    return 0;
}

但表现完全一样。

以下是一些示例输入和输出:

2 3
abc
def

输出:

x��
abc

GDB似乎也没有显示任何内容。请帮忙..

2 个答案:

答案 0 :(得分:5)

这不是“内存泄漏”。问题是,当您在第一行输入两个维度时,第一个gets()调用会读取换行符;它将零个字符放入缓冲区,但是你打印5,这就是你得到一行垃圾的原因。

scanf()格式字符串的末尾添加“\ n”,以便scanf()使用换行符,您的程序将完美运行。请注意,gets()非常不安全;使用fgets(buf, n, stdin)是首选。

答案 1 :(得分:1)

除了'\n'中遗失scanf()之外,您还应为buf分配更多空间:

Example

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

int main()
{
    int m,n; 
    if(scanf("%d%d\n",&m,&n) != 2)
        exit(EXIT_FAILURE);
    char ar[m][n];
    char buf[n+2]; // '\n\0'
    int a,b;
    for(a=0;a<m;a++)
    {
        if (!fgets(buf, n+2, stdin)) exit(EXIT_FAILURE);
        for(b=0;b<n;b++) ar[a][b] = buf[b];
    }
    for(a=0;a<m;a++,printf("\n")) for(b=0;b<n;b++) printf("%c",ar[a][b]);
    return 0;
}

输出

abc
def