【问题标题】:Compilation issues on linuxlinux上的编译问题
【发布时间】:2012-02-27 18:06:50
【问题描述】:

所以我使用 emacs 文本编辑器在 linux(Ubuntu) 中编写了以下代码,它基本上应该分割传入的分隔符上的字符串。当我运行它时,它出现了段错误,我通过 GDB 运行了它,它在 strcpy 处给了我一个错误(我不调用它),但可能在 sprintf 中隐式完成。我不认为我做错了什么,所以我启动到 Windows 并通过 Visual Studio 运行它,它工作正常我是在 Linux 中编写 C 的新手,并且知道问题出在我调用 sprintf() 的 While 循环中(很奇怪,因为循环外的调用写入而不会导致错误)将令牌写入数组。如果有人能告诉我哪里出错了,我将不胜感激。这是代码

/*    split()
 Description:
 - takes a string and splits it into substrings "on" the 
 <delimeter>*/
void split(char *string, char *delimiter)
{
    int i;
    int count = 0;
    char *token;

    //large temporary buffer to over compensate for the fact that we have
    //no idea how many arguments will be passed with a command
    char *bigBuffer[25];

    for(i = 0; i < 25; i++)
    {
        bigBuffer[i] = (char*)malloc(sizeof(char) * 50);
    }

    //get the first token and add it to <tokens> 
    token = strtok(string, delimiter);
    sprintf(bigBuffer[0], "%s", token);

    //while we have not encountered the end of the string keep
    //splitting on the delimeter and adding to <bigBuffer>
    while(token != NULL)
    {
        token = strtok(NULL, delimiter);
        sprintf(bigBuffer[++count], "%s", token);
    }

    //for(i = 0; i < count; i++)
    //printf("i = %d : %s\n", i, bigBuffer[i]);
    for(i = 0; i< 25; i++)
    {
        free(bigBuffer[i]);
    }

} //end split()

【问题讨论】:

  • 您的问题不在于 linux 上的编译——而是您正在编写的程序崩溃。

标签: c linux pointers gcc ubuntu


【解决方案1】:

您没有在循环的最后一次迭代中从strtok 的返回中检查NULL ...所以strtok 可以返回NULL,但您仍然在token 指向sprintf 的指针。

将您的 while 循环更改为以下内容:

while(token = strtok(NULL, delimiter)) sprintf(bigBuffer[++count], "%s", token);

那样你永远不能将NULL指针传递给strtok,因为while循环NULL指针检查将强制token总是有一个有效值,当sprintf被调用时论据。

【讨论】:

  • 非常感谢解决了我的问题。但是您知道为什么它在 Windows 中有效,但在 Linux 中无效,或者这只是 C 在不同系统上表现不同的情况之一
  • 它实际上在 Windows 上“不起作用”......你很幸运它没有崩溃......这就是为什么他们称之为取消引用 NULL 指针未定义的行为 ...你可能会崩溃,或者可能会发生更邪恶的事情,当内存中的一些其他神秘值被破坏并且你不知道为什么时,这会让你头疼:-)
  • 您可以将 while 循环更改为:while ((token = strtok(NULL, delimiter))),它会正常工作。
  • @RichardJ.RossIII:这是一个非常好的建议......我会改变它。
【解决方案2】:

您应该向 gdb 询问程序崩溃位置的完整回溯。您不确切知道它崩溃的位置这一事实意味着您没有要求它提供完整的回溯,这很重要。

【讨论】:

    猜你喜欢
    • 2019-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-12
    • 1970-01-01
    相关资源
    最近更新 更多