【问题标题】:Segmentation fault with strcmp, but the string prints using printfstrcmp 出现分段错误,但使用 printf 打印字符串
【发布时间】:2015-04-23 13:51:31
【问题描述】:

我有一个返回 char** 的标记器方法。结果存储在名为lineTokenschar** 中。当我使用printf() 打印第一个令牌时,我得到了正确的结果,但是当我使用strcmp(lineTokens[0],"Some text") 时,我得到了一个段错误。相应的代码如下。

lineTokens = tokenize(tempString);
printf("token[0] = %s\n", lineTokens[0]);
if(strcmp(lineTokens[0], "INPUTVAR")==0){
    printf("It worked\n");
}

编辑: 我的标记化代码如下

char** tokenize(char* input){
int i = 0;
char* tok;
char** ret;
tok = strtok(input, " ");
ret[0] = tok;
while(tok != NULL){
    printf("%s\n", tok);
    ret[i] = tok;
    tok = strtok(NULL, " ");
    i++;
}
ret[i] = NULL;
return ret;

}

【问题讨论】:

  • I get the correct result,...undefined behaviour 的可能副作用。
  • 欢迎来到 StackOverflow!您是否尝试过使用 gdb 等调试器或 valgrind 等内存工具?
  • 该错误很可能在发布的代码之外。
  • 需要更多细节。发布您的tokenize() 代码。
  • 我打赌tokenize 有一个局部变量,例如char* result[10];it does a return result;。这将返回局部变量的地址。局部变量的内存在printf 处仍然有效,但printf 消耗了足够多的堆栈,以至于当它返回时,内存不再有效。

标签: c segmentation-fault strcmp


【解决方案1】:

当然,如果没有看到tokenize()的代码,就不可能回答这个问题。

我的猜测是该函数中有一些未定义的行为,这可能会破坏堆栈,因此当printf() 运行并实际使用更多堆栈空间时,事情会变糟。未定义行为的事情是它实际上是未定义的,任何事情都可能发生。

在 Valgrind 中运行代码。

【讨论】:

【解决方案2】:

您的标记化功能已损坏。代码中的每个指针都需要指向分配的内存,这里不是这种情况。通过简单地声明一个指针,您不会获得任何内存分配:一个指针仅包含 一个地址,指向在其他地方分配的内存。假设你将它设置为指向“其他地方”,如果你不这样做,它将指向一个随机的垃圾地址。

因此,您需要从头开始重写该函数。要么将指向分配内存的指针作为参数传递,要么在函数内部动态分配内存。但在您这样做之前,我强烈建议您多学习一些数组和指针,例如阅读 C 常见问题解答中的 this chapter

【讨论】:

  • 是的。我是个白痴。标记化功能中的 Malloc 解决了它。刚学C,习惯了Java。不错的 Java。
  • @ScottCorbett Classic Java-programmer-learning-C bug :) 请记住,C 也没有垃圾收集,因此您需要 free() 分配所有内存。无论如何,我强烈建议您阅读c-faq.com 的所有内容,对于初学者和老手来说,这都是极好的阅读材料。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-26
  • 1970-01-01
  • 2020-11-27
  • 1970-01-01
  • 2011-02-27
相关资源
最近更新 更多