打印出数组的单词时会收到分段错误

时间:2012-04-06 02:59:51

标签: c

以下是一段代码,用户输入未知数量的单词,直到输入'E'为止,程序应该停止并打印出所有输入的单词。但是,运行此程序时会产生分段错误。我是否获得了一些我不应该拥有的内存?

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

#define CAPACITY 10
#define NUM_OF_WORDS 10
int main(void)
{
    int num_words = 10;
    char *word= malloc(CAPACITY*sizeof(char));
    char **w=(char **) malloc(num_words*sizeof(char));
    int i;
    for(i = 0 ; scanf("%s", word)==1; ++i)
    {
        if(*word == 'E') 
            break;
        if( i == num_words-1)
            w = (char **)realloc(w, (num_words *=2) * sizeof(char));
        w[i] =(char *) malloc(strlen(word)+1 * sizeof(char));
        strcpy(w[i], word);
    }
    int x = 0;
    for(x = 0 ; x<num_words ; x++)
        printf("%s", w[x]);
    return 0;
}

2 个答案:

答案 0 :(得分:1)

您的初始分配代码为:

char *word = malloc(CAPACITY*sizeof(char));
char **w = (char **) malloc(num_words*sizeof(char));

这两个都分配10个字节的内存。你的第二个应该是:

char **w = (char **) malloc(num_words*sizeof(char *));

或:

char **w = malloc(num_words*sizeof(*w));

这两个指针都为10个指针分配了足够的内存(可能是原始代码的8倍)。第二种可以说是更好的风格;第一个是无可挑剔的经典风格。在C中,malloc()上的强制转换不是必需的;在C ++中,它是。

这可能不是整个问题;这几乎肯定是一个促成因素。

另外,您没有检查内存分配;这是不可取的。你应该经常检查它们。


此代码:

if (i == num_words-1)
    w = (char **)realloc(w, (num_words *=2) * sizeof(char));

正在玩两个帐户(再加上先前诊断出的问题的重复):

  1. 参数列表中的赋值是...通常不被认为是个好主意。我不会编写具有该代码的代码,并且我会发回代码,我被要求审查包含它的代码。这在技术上不是错误的;它会工作。但它并没有让追求维护程序员的生活更轻松。

  2. 您永远不应重新分配w之类的指针,并将新空间分配给同一指针。如果内存分配失败,您将返回一个空指针,因此您丢失了仍然分配的前一个数据的唯一指针。那是内存泄漏。此外,如果内存分配失败,则必须撤消参数列表中的分配,因为分配的空间仍为原始大小。我认为你最好不要使用:

    if (i == num_words - 1)
    {
        size_t new_size = (num_words * 2);
        char **new_data = realloc(w, new_size * sizeof(*new_data));
        if (new_data == 0)
            ...handle error; w is still valid, and num_words is still correct too...
        num_words = new_size;
        w = new_data;
    }
    

答案 1 :(得分:0)

您的变量num_words保存w数组的当前最大大小,但这与数组中实际的单词数不同。

循环遍历w数组时,循环过多的项目 - w的某些元素中没有有效的字符串 - 尝试打印它们会导致段错误。 / p>