【问题标题】:Segmentation fault using strcat使用 strcat 的分段错误
【发布时间】:2012-01-06 08:08:43
【问题描述】:

这是我的代码:

char *name, name_log="log-";

------从用户那里得到“名字”-----

strcat(name_log, name);
char ext[] = ".log";
strcat(name_log, ext);

我最终需要的是 name_log = "log-'name'.log" 但我得到一个分段错误错误:((。我做错了什么,我该如何解决它?谢谢

【问题讨论】:

    标签: c segmentation-fault concatenation strcat


    【解决方案1】:

    name_log指向一个静态的地方:“log-”,表示不能修改,而strcat()的第一个参数必须是可修改的。

    尝试将 name_log 的类型 char* 更改为 char[],例如

    char[20] name_log = "log-";
    

    【讨论】:

    • 为什么大家都发char[20] str;而不是char str[20];?这是我没有意识到的 C1x 中的一些新功能吗?还是您的思想被 Java 烂透了以至于您不知道更好? :-)
    【解决方案2】:

    一个完全不同的解决方案是这样的:

    const char *prefix = "log-";
    const char *suffix = ".log";
    // There's a "char *name" somewhere
    int size_needed;
    char *result;
    
    size_needed = snprintf(NULL, 0, "%s%s%s", prefix, name, suffix);
    result = malloc(size_needed + 1);
    snprintf(result, size_needed + 1, "%s%s%s", prefix, name, suffix);
    
    // "result" now contains the desired string.
    

    snprintf 的好处在于它返回如果有足够的空间它将写入的字符数。这可以通过预先测量要分配多少内存来使用,这使得复杂且容易出错的计算变得不必要。

    如果你碰巧在一个带有asprintf 的系统上,那就更简单了:

    char *result = NULL /* in case asprintf fails */;
    asprintf(&result, "log-%s.log", name);
    // "result" must be released with "free"
    

    【讨论】:

      【解决方案3】:

      字符串文字被分配了固定数量的内存,通常在只读部分中,您需要使用缓冲区。

      char buffer[64] = "log-";
      strncat(buffer,".log",32);
      

      附带说明,strcat 通常是不安全的,您需要使用一些东西来检查它使用的缓冲区的大小或限制它可以连接的内容,例如 strncat

      【讨论】:

      • 呸!懦夫! strcat 仅在您不知道缓冲区足够大的情况下才不安全。真正的 C 程序员会对这样的评论嗤之以鼻:-)
      • @paxdiablo: 是的,但他是初学者,不是真正的 C 程序员:P
      • strncat() 无论如何都坏了,最好使用strlcat()
      • @JeremyP:这是标准功能吗?因为我以前从未见过它
      • @Necrolis:我认为这是 Posix 标准,但似乎不是。不过,它在大多数 Unix 上都可用。
      【解决方案4】:

      首先,如果 this 是您的代码:

      char *name, name_log="log-";
      

      那么name_log是一个char,不是一个char指针。

      假设这是一个错字,你不能像这样附加到字符串文字。对字符串文字的修改是未定义的行为。

      对于可变大小的字符串,就像user 看起来那样,可能最安全的选择是分配另一个足够大的字符串来保存结果,例如:

      char *name, *name_log = "log-", *ext = ".log";
      // Do something to allocate and populate name
      char *buffer = malloc (strlen (name_log) + strlen (name) + strlen (ext) + 1);
      if (buffer == NULL) {
          // Out of memory.
      } else {
          strcpy (buffer, name_log);
          strcat (buffer, name);
          strcat (buffer, ext);
          // Do something with buffer.
          free (buffer);
      }
      

      malloc 确保您有足够的空间来安全地执行所有字符串操作、三个组件的足够字符以及一个空终止符。

      【讨论】:

        【解决方案5】:

        你需要分配内存。您不能以这种方式添加到字符串,因为添加的字符串会进入尚未分配的内存。

        你可以的

        char[20] strarray;
        
        strcat(strarray, "log-");
        strcat(strarray, "abcd");
        

        【讨论】:

        • 这个,此外,name_log 在这样声明时属于char 类型。这甚至不应该编译。
        • @Simon :实际上我认为它是正确的。我现在正在吃我自己的话。但是类型是 char* 所以我觉得应该没问题。
        • 在使用 strcat 之前,请先将 strarray 初始化为空字符串(strarray[0] = '\0' 或类似的)。 (或使用 strncpy 而不是第一个 strcat)。也请使用 strncat 代替 strcat。
        • char[20] strarray?你不是说char strarray[20]吗?
        • 这就是人们写char *a而不是char* a的原因。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-16
        • 2020-10-05
        • 1970-01-01
        • 2013-02-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多