why this does n't works

A

aarklon

Hi all,

why

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


int main(void)
{
char *t[5]; /*= {"BASIC"};*/

strcpy(t[0],"BASIC");
printf("....%s",t[0]);

return EXIT_SUCCESS;
}
/* i am getting segmentation violation in lcc compiler*/

is not working whereas

int main(void)
{
char *t[5] = {"BASIC"};

/*strcpy(t[0],"BASIC");*/
printf("....%s",t[0]);

return EXIT_SUCCESS;
}


is working ?

Does this mean that while using strcpy the char pointer should
always be initialized ...?????
 
P

pereges

i guess the problem arises because you have not allocated any memory
for the string. Probably you can try this because it seems to work for
me:

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

int main(void)
{
char *t[5]; /*= {"BASIC"};*/
int i;
i = strlen("BASIC");
t[0] = malloc(i * sizeof(char));
strcpy(t[0],"BASIC");
printf("....%s",t[0]);

return EXIT_SUCCESS;
}
 
P

pereges

pereges said:
i guess the problem arises because you have not allocated any memory
for the string. Probably you can try this because it seems to work for
me:

Doesn't make it right.


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

Is your space bar broken?
int main(void)
{
char *t[5]; /*= {"BASIC"};*/
int i;
i = strlen("BASIC");

i is 5
t[0] = malloc(i * sizeof(char));

5 * sizeof(char) is 5 (by definition)
strcpy(t[0],"BASIC");

this call attempts to copy SIX bytes, but you only reserved five (assuming
the malloc worked, which you didn't check) - so you've written into memory
you don't own, and the behaviour of your program is now undefined.

Yes, I think I forgot about the null character.
 
R

Richard

pereges said:
i guess the problem arises because you have not allocated any memory
for the string. Probably you can try this because it seems to work for
me:

Seems to. You are lucky. I have listed some issues below. Hope it helps.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main(void)
{
char *t[5]; /*= {"BASIC"};*/
int i;
i = strlen("BASIC");
t[0] = malloc(i * sizeof(char));
strcpy(t[0],"BASIC");
printf("....%s",t[0]);

return EXIT_SUCCESS;
}

Your code has errors. I thought Id try the output of "splint" to make
the diagnosis a little more consistent.

Since I didn't see the previous post I wonder why you are creating an
array of 5 character pointers? or did you think the 5 was the length of
BASIC? It's not clear in the absence of any comment what you really
intend.

From splint(*) :

test2.c:9:3: Assignment of size_t to int: i = strlen("BASIC")

In other words strlen returns a size_t and not an int. Personally when I
write C I tend to still use "int" where I KNOW the string is short
enough. But its not "correct". Use a size_t.

Also you only malloc enough for the "BASIC" part and not for the
trailing zero to indicate "end of string". Look up "strings" in C. Read
the manual for strlen and strcpy. This is one of the most basic but
important things to know in C.

More from splint:

test2.c:10:34: Parameter to sizeof is type char: sizeof(char)
Operand of sizeof operator is a type. (Safer to use expression, int *x =
sizeof (*x); instead of sizeof (int).) (Use -sizeoftype to inhibit warning)

Personally, for me, this line would just be

t[0] = malloc(strlen("BASIC")+1);

But even then we have a problem that something like splint can tell us
no matter how much we think we know best:

strcpy (t[0], ...)
A possibly null pointer is passed as a parameter corresponding to a formal
parameter with no /*@null@*/ annotation. If NULL may be used for this
parameter, add a /*@null@*/ annotation to the function parameter declaration.

Why is this? It's because you did not check for malloc returning NULL,
but that is another story and down to good programming practices.

So following that hint we can do:

char *p = malloc(strlen("BASIC")+1);
if(p==NULL)
return EXIT_FAILURE;
t[0]=p;
strcpy(t[0],"BASIC");


(*)(Splint is a tool for statically checking C programs for
security vulnerabilities and coding mistakes. With minimal effort,
Splint can be used as a better lint. If additional effort is invested
adding annotations to programs, Splint can perform stronger checking
than can be done by any standard lint. See http://www.splint.org/ ).
 
K

Kenneth Brody

Richard said:
(e-mail address removed) said:
[... snip first version which SEGV's ...]
int main(void)
{
char *t[5] = {"BASIC"};

/*strcpy(t[0],"BASIC");*/
printf("....%s",t[0]);

return EXIT_SUCCESS;
}


is working ?

No, it just isn't breaking in the way you were hoping it to break.
Undefined behaviour *doesn't* necessarily mean "it will crash".

Isn't this second version perfectly well-defined? Doesn't the line:

char *t[5] = {"BASIC"};

mean:

t is an array of 5 character pointers, the first one points
to the literal "BASIC", and the rest are NULL

and so the reference to t[0] means the string "BASIC"?
Gee, ya think?


--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
B

Barry Schwarz

Richard said:
(e-mail address removed) said:
[... snip first version which SEGV's ...]
int main(void)
{
char *t[5] = {"BASIC"};

/*strcpy(t[0],"BASIC");*/
printf("....%s",t[0]);

return EXIT_SUCCESS;
}


is working ?

No, it just isn't breaking in the way you were hoping it to break.
Undefined behaviour *doesn't* necessarily mean "it will crash".

Isn't this second version perfectly well-defined? Doesn't the line:

char *t[5] = {"BASIC"};

mean:

t is an array of 5 character pointers, the first one points
to the literal "BASIC", and the rest are NULL

Yes
and so the reference to t[0] means the string "BASIC"?

Yes but it might be better phrased as'"the string literal "BASIC"'.

It is only well defined as long as there is no attempt to update the
characters pointed to by t[0]. Any attempt to do so (as implied by
the commented call to strcpy) invokes undefined behavior.


Remove 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

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,679
Members
48,796
Latest member
Greg L.

Latest Threads

Top