【问题标题】:Unfathomable C structures深不可测的C结构
【发布时间】:2013-05-10 04:24:47
【问题描述】:

您好,我遇到了一些我真的不明白 C 中结构原理的东西。 我的结构之一包含 2 个字符串(名为“seq”和“foldedSeq”)。这两个字符串(应该)具有相同的尺寸。 但是,当我尝试修改一个时,第二个会自动在字符串的同一指定位置进行相同的修改。

这是一段有趣的代码:

typedef struct MD {

 int nb_line;
 int nb_colomn;
 EM ** matrix; 
 char * seq;  // Initial sequence.
 char * foldedSeq;
} MD;


void set_sequences(MD * M, char * seq) {

 M->seq = seq;
 M->foldedSeq = M->seq; //Purpose: give to foldedSeq the seq dimensions (perhaps it is useless).


 printf("seq= %s\tstrlen= %d\nM->seq= %s\nM->foldedSeq= %s\n", seq, strlen(seq), M->seq, M->foldedSeq);
  // Up to this point 'seq' = 'foldedSeq'


 int i;
 for( i = 0; i < strlen(seq); i++) {
  M->foldedSeq[i] = '-'; // Original purpose: make 'foldedSeq' string filled with hyphens only.
 } 

 printf("seq= %s\tstrlen= %d\nM->seq= %s\nM->foldedSeq= %s\n", seq, strlen(seq), M->seq, M->foldedSeq);
// Here is the problem: the string 'seq' REALLY IS modified alongside with 'foldedSeq'... WHY? :(
}

既然我写了“M->foldedSeq[i]”应该修改,为什么“M->seq[i]”也要修改??

感谢您阅读并为我提供解释,我的逻辑在这里找到了死胡同。

【问题讨论】:

    标签: c structure


    【解决方案1】:
     M->seq = seq;
     M->foldedSeq = M->seq;
    

    和说的一样

     M->seq = seq;
     M->foldedSeq = seq;
    

    它们都指向内存中的相同位置。所以修改一个就是修改两个。

    您可能想要做的是 malloc 一块与另一个长度相同的内存块。

     M->foldedSeq = calloc(strlen(seq) + 1, sizeof(char));
    

    【讨论】:

    • 你不是在malloc 后面缺少strcpy 吗?就目前而言,代码提供了一个适当大小的未初始化内存块。
    • @simonc 评论只是说它想要相同的长度而不是相同的内容。他立即用- 填充它。
    • q 是什么?您的意思是 + 1 表示 null 终止吗?
    • @FDinoff 如果您查看代码,有几行 printf 假定 M-&gt;foldedSeq 是一个以 nul 结尾的字符串。这些将根据您的建议更改产生未定义的结果。
    • @Lundin q 是一个错字。此外,c 中的每个字符串都以空终止符结尾。 strlen 没有考虑到这一点。
    【解决方案2】:

    您所看到的是简单的指针别名,这是 C 语言的一个基本特性。因为您明确地分配了seqfoldedSeq 成员指向同一位内存,并且通过一个指针进行的修改将被另一个见证。如果这不是您想要/想要的,您需要先复制 seq 的内存块,然后再将其分配给 foldedSeq 以保持两者不同。

    【讨论】:

      【解决方案3】:

      这一行:

       M->foldedSeq = M->seq;
      

      foldedSeq 指针设置为与seq 相同的值。它不是创建新空间并将seq 的内容复制到foldedSeq,这可能是混乱的地方。因此,当您修改其中一个时,另一个也将被修改。一种可能的解决方案是使用strdup:

      M->foldedSeq = strdup( M->seq ) ;
      

      【讨论】:

        【解决方案4】:

        因为它们都指向相同的内存地址,并且当您修改一个时,您正在修改另一个。 此分配:M-&gt;foldedSeq = M-&gt;seq; 只是分配内存位置,而不是进行任何形式的复制。 如果要将它们分开,则必须分配内存并将字符串复制到新内存中。

        【讨论】:

          【解决方案5】:

          尝试: M-&gt;foldedSeq = strdp(M-&gt;seq)如果你也想复制内容。

          或者:

          M-&gt;foldedSeq = malloc(strlen(M-&gt;seq) + 1); 只是拥有一个相同大小的新内存空间。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-07-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-12-18
            相关资源
            最近更新 更多