Alexandre Toqué
Alexandre Toqué

Reputation: 193

Unfathomable C structures

Hello I am experiencing something I really don't understand the principle with structures in C. One of my structures contains 2 character strings (named 'seq' and 'foldedSeq'). Both these strings (should) have the same dimensions. However when I try to modify one, the second automatically takes the same modifications at the same specified place of the string.

Here is the interesting chunk of code:

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? :(
}

Since I wrote "M->foldedSeq[i]" should be modified, why would "M->seq[i]" be modified as well ??

Thank you for reading and providing me explanations, my logic found a dead end here.

Upvotes: 0

Views: 166

Answers (5)

Shafik Yaghmour
Shafik Yaghmour

Reputation: 158499

This line:

 M->foldedSeq = M->seq;

is setting the foldedSeq pointer to the same value as seq. It is not creating new space and copying the contents of seq to foldedSeq which is maybe where the confusion is. So when you modify either one the other will be modified as well. One possible solution is to use strdup:

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

Upvotes: 0

FDinoff
FDinoff

Reputation: 31429

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

is the same as saying

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

They are both pointing to the same location in memory. So modifying one is modifying both.

Probably what you want to do instead is malloc a block of memory that is the same length as the other.

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

Upvotes: 2

yoones
yoones

Reputation: 2474

Try either: M->foldedSeq = strdp(M->seq) if you want to copy the content too.

Or:

M->foldedSeq = malloc(strlen(M->seq) + 1); to just have a new memory space of the same size.

Upvotes: 0

edtheprogrammerguy
edtheprogrammerguy

Reputation: 6039

Because they both point to the same memory address and when you modify one you are modifying the other. This assignment: M->foldedSeq = M->seq; is just assigning memory locations, not doing any sort of copy. If you want to keep them separate, you will have to allocate memory and copy the string into the new memory.

Upvotes: 0

Scott Jones
Scott Jones

Reputation: 2908

What you're witnessing is simple pointer aliasing, a basic feature of the C language. Because you explicitly assign both seq and foldedSeq members to point to the same bit of memory, and modifications through one pointer will be witnessed by the other. If that's not what you intended/wanted, you'd need to copy the memory block of seq before assigning it to foldedSeq to keep the two distinct.

Upvotes: 0

Related Questions