动态分配的字符串数组内存似乎不起作用

时间:2018-02-16 08:57:43

标签: c pointers memory

我正在尝试让这个函数读取一个句子并将每个单词存储到一个字符串数组中。我将句子存储在line

char** storewords(char* line){    
    char** newArr = (char**) malloc(sizeof(char*)); 
    free(word);
    return newArr;
}

我稍后调用此函数并尝试打印数组中的每个单词:

main {
    // ........ //
    //function to get a line into line//
}

void printArr(char** newArr) {
    int i = 0; 
    }
}

我使用while (newArr[i] != NULL)来告诉程序迭代数组直到遇到NULL项。

记忆似乎被奇怪地分配了,因为当我把它打印出来时,有些单词似乎有时不打印,但其他时候效果很好。

例如,如果我输入“hello hi”,我会得到:

newArr 0: 
newArr 1: hi

和“你好我的名字是”将得到:

newArr 0: hello
newArr 1: my
newArr 2: name
newArr 3: 

但如果我输入更长的内容,比如“你好我的名字是stackoverflow”,我会得到正确的结果。

2 个答案:

答案 0 :(得分:0)

如果我理解storewords正确背后的想法,您可以:

a)以单个字符指针

开头

b)每次调用realloc

时添加额外的字符指针

这样你就可以将最后一个char指针设置为NULL,这样它就可以作为一个"数组结束"标记

如果这是您的意图,则问题是realloc

char** newArr = (char**) malloc(sizeof(char*));  // Now you have 1 char pointer
char* word;
int count = 0;  // Notice that you (correctly) initialize count to zero

word = strtok(line, " ");
while (word != NULL) {            
    newArr = (char**) realloc(newArr, sizeof(char*) * (count + 1));
                      // The first time you execute the realloc, you want to
                      // increase the number of char pointers from 1 to 2.
                      // But count is zero so count + 1 is only 1.
                      // In other words, you only got 1 element but
                      // you wanted 2 elements.

所以改为:

    newArr = (char**) realloc(newArr, sizeof(char*) * (count + 2));

count" 2" 2"你想要的元素数量。

BTW:直接在目标变量中执行realloc是不好的。总是用两个临时变量来做。检查是否为NULL。如果不为NULL,则将temp变量分配给目标。

BTW:无需转换reallocmalloc

返回的值

顺便说一句:删除free(word);它什么都不做,你不想在这里取消任何东西。

因此,考虑到上述情况,您的功能可能是:

char** storewords(char* line){    
    char** tmp;
    char** newArr = malloc(sizeof(char*)); 
    char* word;
    int count = 0;

    word = strtok(line, " ");
    while (word != NULL) {            
        tmp = realloc(newArr, sizeof(char*) * (count + 2));
        if (tmp == NULL)
        {
            // realloc failed - add error handling - for now just exit
            exit(1);
        }
        newArr = tmp;
        newArr[count] = malloc(strlen(word) * sizeof(char) + 1);
        // put the word in array
        sscanf(word, "%s", newArr[count]);
        count++;

        word = strtok(NULL, " ");
    }
    newArr[count] = NULL; //set the last item in the array as null
    return newArr;
}

答案 1 :(得分:0)

当你玩弦时,你应该总是非常小心。在这里你使用指针指针,所以像指针一样使用它们而不是用作数组并混合和匹配。在编写程序时,首先要安排算法如何逐步实现,然后将其写在一篇论文中,该论文也称为procedural design。我在下面修改了你的程序,看看你的错误。另请参阅我如何仅使用指针指针作为指针而不是像数组一样。因此,我将printArr的代码留给您将其从数组更改为指针,以便您可以享受它。祝你好运!

char** storewords(char* line){
    char** newArr = (char**) malloc(sizeof(char*));
    char* word;
    int count = 1;
    word = strtok(line, " ");
    *newArr = word; //store the pointer of word at the first location
    while (word != NULL) {
        newArr = (char**) realloc(newArr, sizeof(char*) * (count + 1));
        //newArr[count] = (char*)malloc(strlen(word) * sizeof(char) + 1);//you dont need this line at all
        // put the word in array
        //sscanf(word, "%s", newArr[count]);
        word = strtok(NULL, " ");//get the next word
        *(newArr+count)=word;//store the next word here
        count++;

    }
    *(newArr+count) = NULL; //set the last item in the array as null
    free(word);
    return newArr;
}

void printArr(char** newArr) {
    int i = 0;
    while (newArr[i] != NULL) {
        printf("newArr %d: %s\n", i, newArr[i]);
        i++;
    }
}

int main() {
    // ........ //
    //function to get a line into line//
    char *line = malloc(100);
    strcpy(line, "Hello world how are you!");
    char** newArr = storewords(line);
    printArr(newArr);
    return 0;
}