c - 重新分配,字符**,段错误

标签 c segmentation-fault realloc

有一个函数。它是 add_lexem 并在指定数组的末尾添加一个元素 (char *) and。如果没有剩余内存,它会分配一些额外的内存 (100 * sizeof(char *))。该函数会导致段错误,这就是问题所在。

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

void add_lexem(char **lexems, int *lexemsc, int *lexem_n, const char *lexem)
{
    if (*lexem_n >= *lexemsc) {
        lexems = realloc(lexems, sizeof(char *) * (*lexemsc + 100));
        *lexemsc += 100;
    }

    char *for_adding = malloc(sizeof(char) * strlen(lexem));
    strcpy(for_adding, lexem);
    lexems[*lexem_n] = for_adding;
    (*lexem_n)++;
}

int main(void)
{
    char **D = malloc(sizeof(char *) * 2);
    int lexemsc = 2;
    int lexem_n = 0;

    add_lexem(D, &lexemsc, &lexem_n, "MEOW");
    printf("%s\n", D[0]);

    add_lexem(D, &lexemsc, &lexem_n, "BARK");
    printf("%s\n", D[1]);

    // in this place lexem_n becomes equal lexemsc
    add_lexem(D, &lexemsc, &lexem_n, "KWARK"); 
    printf("%s\n", D[2]);

    return 0;
}

输出必须是

MEOW
BARK
KWARK

不过是

MEOW
BARK
Segmentation fault (core dumped)

最佳答案

你正在按值传递你的 lexeme 参数,而它应该按地址传递:

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

// removed unused void ccat(char *str, char c)

void add_lexem(char ***lexems, int *lexemsc, int *lexem_n, const char *lexem)
{
    if (*lexem_n >= *lexemsc) {
        *lexems = realloc(*lexems, sizeof(char *) * (*lexemsc + 100));
        *lexemsc += 100;
    }

    char *for_adding = malloc(sizeof(char) * strlen(lexem)+1);
    strcpy(for_adding, lexem);
    (*lexems)[*lexem_n] = for_adding;
    (*lexem_n)++;
}

int main(void)
{
    char **D = malloc(sizeof(char *) * 2);
    int lexemsc = 2;
    int lexem_n = 0;

    add_lexem(&D, &lexemsc, &lexem_n, "MEOW");
    printf("%s\n", D[0]);

    add_lexem(&D, &lexemsc, &lexem_n, "BARK");
    printf("%s\n", D[1]);

    // in this place lexem_n becomes equal lexemsc
    add_lexem(&D, &lexemsc, &lexem_n, "KWARK");
    printf("%s\n", D[2]);

    return 0;
}

输出

MEOW
BARK
KWARK

注意:三重间接(即 3-start-programming)并不是一件容易进入的事情,尽管它实际上适合您在这里似乎要尝试做的事情。仔细阅读上面的代码并确保您理解它是如何工作的。

编辑:为添加的字符串添加终止符空间。 (不知道为什么我错过了它,因为它似乎是其他人在第一次审查时就注意到的,呃)。

注意:参见 @wildplasser's answer对于这个问题。老实说,这是最好的方法,因为它加强了字符串指针数组和 said-same 的大小之间的关系。如果可以重组您的代码以使用该模型,您应该这样做,并在这样做时选择该答案作为“正确”解决方案。

关于c - 重新分配,字符**,段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23198875/

相关文章:

php - 使用 sftp 和 ssh2 的 fopen 段错误

c - 在链中 fork N 个进程

c - 试图从用户那里读取 double,出现段错误

c - 如何检测我的哪一段代码生成 "Fatal error: glibc detected an invalid stdio handle"错误?

c - 数组搜索 C 中的段错误

C - realloc 导致崩溃

C - 尝试在 linux 中构建一个简单的 shell 并在循环中使用 strtok、realloc 时遇到问题

c++ - 理解realloc

c - typedef 结构混淆中的指针

linux中的C用户名——获取当前用户名