struct and string pointers

P

Paul

Hi,

I'm new to c and I have no idea what I'm doing wrong. Running the
attached program gives me the output:

t1: 1234567890123456STRANGE
t2: STRANGE

But only when the first string is 16 or 32 (...) characters long. I'm
running gcc 3.3 from apple (build 1495) on mac osx panther (gcc -ansi
-pedantic -Wall).

Thanks for any help! / Paul

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct target {
char *t1;
char *t2;
};


void add_to_t (struct target *t, const char *s) {
char *temp;
static int target = 0;

temp = malloc(strlen(s) * sizeof(char));

strcpy(temp, s);

if (target == 0)
t->t1 = temp;
else
t->t2 = temp;
++target;
}

int main (void) {
struct target t;
char *s1 = "1234567890123456";
char *s2 = "STRANGE";

add_to_t(&t, s1);
add_to_t(&t, s2);

printf("t1: %s\nt2: %s\n", t.t1, t.t2);

return 0;
}
 
P

Paul Diaconescu

Sorry, a glitch. The text was:


When i run this i get,

t1: 1234567890123456STRANGE
t2: STRANGE ^
(this is the strange part)

but only when the first string is 16 or 36 (...?) chars long.
Whats wrong with it? I'm running gcc 3.3 on mac os x panther (-ansi
-pedantic -Wall).

/ Paul
 
C

CBFalconer

Paul said:
I'm new to c and I have no idea what I'm doing wrong. Running the
attached program gives me the output:
.... snip ...

And also to newsgroups, evidently. Do not use attachments. Cut
and paste complete compilable programs into your message.
Attachments are potentially evil, and many ISPs automatically
delete them in non-binary newsgroups.
 
G

Gerald R. Generoso

Sorry, a glitch. The text was:


When i run this i get,

t1: 1234567890123456STRANGE
t2: STRANGE ^
(this is the strange part)

but only when the first string is 16 or 36 (...?) chars long.
Whats wrong with it? I'm running gcc 3.3 on mac os x panther (-ansi
-pedantic -Wall).

/ Paul

It executed properly on my system or it was just lucky :)
As far as I can tell in your add_to_t function you have a local pointer
(struct target *t) which doesn't point to a valid memory location.

Gerald R. Generoso
 
M

Mark McIntyre

Hi,

I'm new to c and I have no idea what I'm doing wrong. Running the
attached program gives me the output:

t1: 1234567890123456STRANGE
t2: STRANGE

.....but only for strlen(s1) = multiples of the default alignment on
your computer...... this is a hint !
temp = malloc(strlen(s) * sizeof(char));

Think about how long strlen(s) is, and whether it includes the
terminating null on the string. Then think about how your compiler
places objects in memory, and whether it leaves space between them...
 
B

Barry Schwarz

Hi,

I'm new to c and I have no idea what I'm doing wrong. Running the
attached program gives me the output:

t1: 1234567890123456STRANGE
t2: STRANGE

But only when the first string is 16 or 32 (...) characters long. I'm
running gcc 3.3 from apple (build 1495) on mac osx panther (gcc -ansi
-pedantic -Wall).

Thanks for any help! / Paul

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct target {
char *t1;
char *t2;
};


void add_to_t (struct target *t, const char *s) {
char *temp;
static int target = 0;

temp = malloc(strlen(s) * sizeof(char));

This does not allocate enough space. strlen returns the number of
characters in the string NOT including the terminating '\0'. However,
if you want to copy the string, you must have enough space to include
the '\0'.

sizeof(char) is guaranteed to always be 1 so you don't need it in the
argument expression.
strcpy(temp, s);

You have now invoked undefined behavior by running beyond the end of
the area temp points to.
if (target == 0)
t->t1 = temp;
else
t->t2 = temp;
++target;
}

int main (void) {
struct target t;
char *s1 = "1234567890123456";
char *s2 = "STRANGE";

add_to_t(&t, s1);
add_to_t(&t, s2);

Apparently, when strlen(s) is a multiple of 16, the area allocated in
this second call to add_to_t immediately follows the area allocated in
the first call, overlaying the '\0' which is just outside the area
allocated. This is a really unlucky manifestation of undefined
behavior because it led you to believe your code was correct.
printf("t1: %s\nt2: %s\n", t.t1, t.t2);

In the situation described, t1 does not point to a string (because the
'\0' is flat out missing or not part of the allocated memory).
return 0;

Your program never frees the memory allocated by add_to_t.
This is called a memory leak and is bad programming practice (tm).



<<Remove the del for email>>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
474,135
Messages
2,570,783
Members
47,341
Latest member
hanifree

Latest Threads

Top