Reputation: 191
I have to do an exercise and I have this structure given:
typedef struct {
char *str;
unsigned int len;
} String;
My Task is to write a String Concat which concats "Kartoffel"
and "puffer"
to "Kartoffelpuffer"
(potato fritter).
String concat(String l, String r)
Both Strings l
and r
should not be changed after running the function.
First I created the two Strings in the main:
String1 *l = malloc(sizeof(String1));
String1 *r = malloc(sizeof(String1));
(*l).str = malloc(sizeof("Kartoffel"));
(*r).str = malloc(sizeof("puffer"));
(*l).str = "Kartoffel";
(*r).str = "puffer";
(*l).len = 9;
(*r).len = 6;
Then I wrote the concat function:
String1 concat(String1 l, String1 r) {
unsigned int i = 0;
String1 *newStr = malloc(sizeof(String1));
/* +1 for '\0' at the end */
newStr->str = malloc(l.len + r.len + 1);
newStr->str = l.str;
/* The following line is not working */
newStr->str[l.len] = *r.str;
newStr->len = l.len + r.len;
return *newStr;
}
What Im trying to do is working with pointer arithmetic.
When there is a pointer which points to the beginning of a storage area like char *str
, it should be possible to move the pointer with a[b]
or *((a) + (b))
right? When I run the code I get Segmentation fault (I hope its the right translation. Original: "Speicherzugriffsfehler"
).
If someone could give me a hint I would be thankful. PS: Sorry for my English.
Upvotes: 0
Views: 915
Reputation: 191
Thank you very much for your help! I wrote another method to copy the string as you guys said.
char * copyStr (char * dest,char * src){
unsigned int index;
for (index = 0; src[index] != '\0'; index++) {
dest[index] = src[index];
}
dest[index] = '\0';
return dest;
}
And I edited my concat like that:
String1 concat (String1 l, String1 r){
String1 *newStr = malloc(sizeof(String1));
newStr->str = malloc(l.len+r.len+1);
copyStr(newStr->str,l.str);
copyStr((newStr->str+l.len),r.str);
newStr->len = l.len+r.len;
return *newStr;
}
with newStr->str+l.len
the pointer will be moved. If l.len is 9, the pointer will point to the 10th byte, which is the end of the first string l. So the the String r will be copied in the memory storage behind the first string l.
Upvotes: 1
Reputation: 2508
After allocating memeory to newStr
and newStr->str
Two pointers could be used. char *to, *from;
Set the pointers with to = newStr->str;
and from = l.str;
copy the characters with *to = *from;
Advance the pointers with to++;
and from++;
Repeat until *from == 0
Set from
with from = r.str;
to
does not need to be reset as it is correctly positioned at the end of newStr->str
.
Repeat the copy of characters.
Repeat advancing the pointers.
Set a terminating 0 with *to = 0;
Upvotes: 1
Reputation: 11020
First, (*l).str = "Kartoffel";
makes (*l).str
point to the "Kartoffel"
string literal, meaning that the original memory allocated to (*l).str
with malloc()
is lost. Same for (*r).str = "puffer";
. One of the things you can do to avoid this is copy the string into the allocated buffer by looping over the characters in a for loop (since you can't use string.h
).
Then, in your concat()
function, you do the same thing. You allocate the memory for newStr->str
with malloc()
(properly allocating an extra char
for the null-terminator), but on the next line you re-assign that pointer to point to l.str
, which is still pointing to the string literal. Then, with newStr->str[l.len] = *r.str;
you are attempting to modify the string literal, which in C is undefined behavior.
The way to fix this could be, again, to copy the two strings into the buffer allocated with newStr->str = malloc(l.len+r.len+1);
.
Upvotes: 2