【问题标题】:Strcpy() corrupts the copied string in Solaris but not Linuxstrcpy() 在 Solaris 而不是 Linux 中损坏了复制的字符串
【发布时间】:2011-02-08 16:45:39
【问题描述】:

我正在为一个类编写 C 代码。这个类要求我们的代码在学校服务器上编译运行,这是一台 sparc solaris 机器。我正在运行 Linux x64。

我要解析这一行(这不是实际代码,而是输入到我的程序中):

while ( cond1 ){ 

我需要将“while”和“cond1”捕获到单独的字符串中。我一直在使用strtok() 来执行此操作。在 Linux 中,以下几行:

char *cond = NULL;
cond = (char *)malloc(sizeof(char));
memset(cond, 0, sizeof(char));
strcpy(cond, strtok(NULL, ": \t\(){")); //already got the "while" out of the line

将正确捕获字符串“cond1”。但是,在 solaris 机器上运行它会得到字符串“cone1”。

请注意,在我的程序中的许多其他情况下,字符串被正确复制。 (例如,“while”)被正确捕获。

有人知道这里发生了什么吗?

【问题讨论】:

    标签: c solaris strcpy sparc


    【解决方案1】:

    行:

    cond = (char *)malloc(sizeof(char));
    

    恰好分配一个char 用于存储,然后您将复制多个到其中-strcpy 需要至少放入空终止符,但在您的情况下,还有您的@987654324 的结果@ 也一样。

    它可能在不同的系统上工作的原因是malloc 的某些实现无论您要求什么实际值都会以特定的分辨率(例如,16 字节的倍数)分配,因此您可能有一些免费的缓冲区末尾的空间。但是您正在尝试的仍然是非常未定义的行为。

    未定义的行为有时可能会起作用这一事实绝不会免除您避免此类行为的责任。

    分配足够的空间来存储strtok 的结果,你应该没问题。

    最安全的方法是动态分配空间,使其至少与您传递给strtok 的字符串一样大。这样就不会有溢出的可能性(除了奇怪的边缘情况,其他线程可能会在你背后修改数据,但如果是这种情况,strtok 无论如何都是一个非常糟糕的选择)。

    类似(如果 instr 是您的原始输入字符串):

    cond = (char*)malloc(strlen(instr)+1);
    

    这保证从instr 提取的任何令牌都适合cond

    顺便说一句,sizeof(char) 根据定义始终为 1,因此您无需乘以它。

    【讨论】:

    • 执行char *token = strtok(NULL, "stuff"); 之类的操作,然后将新缓冲区分配为cond = (char*)malloc(strlen(token)+1); 然后strcpy(cond, token); 您可以节省一些内存,具体取决于这些令牌保留多长时间,以及输入字符串是否恰好是怪物。
    • 这样做的问题是,您正在为每个标记而不是每个输入字符串(很可能是行)进行分配和释放。我怀疑这样做对性能的影响将超过使用更少内存的任何收益,除非这些行真的很大。但这是一个主观的事情,取决于你的需求,所以我不会过多争论这一点。
    【解决方案2】:

    您只为 1 个字符分配了内存,但您尝试存储至少 6 个字符(您需要空间用于终止 \0)。解决这个问题的快速而肮脏的方法就是说

    字符条件[128]

    而不是 malloc。

    【讨论】:

      【解决方案3】:

      cond 被分配一个字节。 strcpy 正在将至少两个字节复制到该分配中。也就是说,您在分配中写入的字节数超过了空间。

      修复它的一种方法是使用char *cond = malloc (1000); 而不是你所拥有的。

      【讨论】:

      • 好电话。那么,其他比这更长的字符串被正确复制是不是纯属运气?
      • @strictlyrude27:是的,纯属巧合。
      猜你喜欢
      • 2013-03-17
      • 2013-11-12
      • 1970-01-01
      • 2020-02-17
      • 1970-01-01
      • 2011-07-14
      • 1970-01-01
      • 2017-02-24
      • 2019-05-16
      相关资源
      最近更新 更多