【问题标题】:Segmentation fault in accessing & modifying string (char*) array in C在 C 中访问和修改字符串 (char*) 数组时出现分段错误
【发布时间】:2018-10-24 04:04:00
【问题描述】:

我在尝试编译一段时间的程序上遇到分段错误(gdb 在回溯上打印“??”),并且在尝试了很多事情之后(例如重新编程我使用的数据结构)现在应该可以工作了)我仍然不断收到段错误,尽管现在它给了我一行(我在此处添加了评论)。

getMains() 运行多次以标记同一文件中的不同行。

我希望 mains 是一个大小为 4 的数组,但是当将它作为“char * mains[4]”传递时,我尝试将一个我从未处理过的数组 (*)[4] 传递给它时遇到编译错误事先(刚开始使用C)。我假设如果我尝试访问任何未使用的部分,这可能是一个问题,但是在初始化数组的索引时会出现问题。

我试图开始工作的代码,其中“char *** mains”参数从一个单独的函数“runner”中获取 &(char **),我想对其进行编辑,以便我可以在“runner”中查看它的内容:

bool getMains(FILE * file, char *** mains)
{
    char line[256];
    int start = 0;
    char * token;
    const char * mainDelim = "\t \n\0", * commDelim = "\n\t\0";

    if(fgets(line, sizeof(line), file) == NULL)
        return false;

    while(line[0] == '.')
        if(fgets(line, sizeof(line), file) == NULL);
            return false;

    if(line[0] == '\t' || line[0] == ' ')
    {
        (*mains)[0] = " ";
        start = 1;
    }

    token = strtok(line, mainDelim);
    int i;
    for(i = start; token != NULL; ++i)
    {
        (*mains)[i] = strdup(token); // <- gdb: Segmentation Fault occurs here

        if(i % 3 == 2)
            token = strtok(NULL, commDelim);
        else
            token = strtok(NULL, mainDelim);
     }

     free(token); // Unsure if this was necessary but added in case.
     return true;
}


/* Snippet of code running it... */
void runner(FILE * file) {
    char ** mains;
    if(!getMains(*file, &mains))
        return;
    while(strcmp(mains[1], "END") != 0){
        /* do stuff lookinig through indices 0, 1, 2, & 3 */
        if(!getMains(*file, &mains))
            break;
    }
}

关于这个或只是通过其他函数安全地修改数组的任何提示?

我是否应该将 getMains() 更改为“getMains(FILE * file, char ** mains[4]);”并将其传递给 &"char * mains[4]") 使其成为所需的设定大小?或者这也会产生错误?

【问题讨论】:

  • char ** mains; / char *** mains 在你开始玩之前永远不会指向任何东西。
  • 问题出在调用这个的函数中。我敢打赌你没有正确分配mains
  • @perreal 它在下面...向下滚动
  • 另外,“2星应该对每个人都足够了”
  • 考虑通过return语句返回主函数resilt,即char** getMains(FILE * file)

标签: c arrays pointers segmentation-fault


【解决方案1】:

你需要为电源分配内存,它应该是这样的:

char ** mains;
mains = malloc(some number N * sizeof(char*));

如果你不使用 strdup,你需要这样的东西,它会为你分配内存:

for (int i = 0; i < N; ++i) {
  mains[i] = malloc(some number K);
}

在所有情况下,不要忘记在收到来自mallocstrdup 的每个指针时调用free。如果程序在您调用free 之后立即结束,您可以跳过此部分。

【讨论】:

  • 也是免费的(token);肯定是错误的—— strtok() 返回的值在 line..line+256 之内;不是堆返回的东西。
  • 不,mains[i]不用分配,后面会被strduped。
  • 非常感谢!我终于让它工作而没有以分段错误结束!在此之后我需要开始更多地研究内存分配
  • @n.m.等等,如果我使用 strdup,我不必这样做?不过,我仍然必须为电源做这件事,对吗?
  • @fabian 两者都是
猜你喜欢
  • 2011-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-19
  • 1970-01-01
  • 2011-09-03
  • 1970-01-01
相关资源
最近更新 更多