473,408 Members | 1,749 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,408 software developers and data experts.

Write to dynamic two dimension array outside the range without Segmentation fault

This code snippet is an exercise on allocating two dimension array
dynamically. Though this one is trivial, is it a correct one?
Furthermore, when I tried to make these changes to the original
example:

for (i = 0; i < ROW + 2; ++i){ /*line 14*/
strcpy(array[i], "C! C!"); /*line 15*/

Apparently, the modified code wrote to the memory unit outside the
allocated array, but the program ran well and there was no Segmentation
fault. Thank you.

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

#define ROW 4
#define COL 3

int main(void){
char (*array)[COL];
int i;

array = malloc(ROW * sizeof *array);
if (array){
for (i = 0; i < ROW; ++i){ /*line 14*/
strcpy(array[i], "C!"); /*line 15*/
printf("%s\n", array[i]);
}
}
free(array);

return 0;
}

Sep 3 '06 #1
27 3187

lovecreatesbea...@gmail.com wrote:
strcpy(array[i], "C!"); /*line 15*/
printf("%s\n", array[i]);
strcpy doesn't nul terminate, so your call to printf will fault.

Sep 3 '06 #2
Op 3 Sep 2006 10:28:48 -0700 schreef bw*****@yahoo.com:
lovecreatesbea...@gmail.com wrote:
> strcpy(array[i], "C!"); /*line 15*/
printf("%s\n", array[i]);

strcpy doesn't nul terminate, so your call to printf will fault.
strcpy does, memcpy doesn't.
printf won't fail here.
--
Coos
Sep 3 '06 #3
bw*****@yahoo.com wrote:
lovecreatesbea...@gmail.com wrote:
> strcpy(array[i], "C!"); /*line 15*/
printf("%s\n", array[i]);

strcpy doesn't nul terminate,
What on earth makes you think that? strcpy is a *string* copy, so of
course it is defined to copy the null termination, otherwise it would be
called something like,
CopyJustTooLittleOfAStringToBeUsefull99PercentOfTh eTimeOrMore.
so your call to printf will fault.
Even if you were write about strcpy (which you are not) that would still
not guarantee that the call to printf would fault.
--
Flash Gordon
Sep 3 '06 #4
lovecreatesbea...@gmail.com wrote:
This code snippet is an exercise on allocating two dimension array
dynamically. Though this one is trivial, is it a correct one?
Furthermore, when I tried to make these changes to the original
example:

for (i = 0; i < ROW + 2; ++i){ /*line 14*/
strcpy(array[i], "C! C!"); /*line 15*/

Apparently, the modified code wrote to the memory unit outside the
allocated array, but the program ran well and there was no Segmentation
fault. Thank you.
Excuse me mister policeman, but why are you telling me I should not
drive with my eyes close? I just managed to drive 100 yards down the
road with my eyes closed and I didn't crash!

Just because you do something wrong it does not guarantee a crash. All
it guarantees is that you have done something wrong.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define ROW 4
#define COL 3

int main(void){
char (*array)[COL];
int i;

array = malloc(ROW * sizeof *array);
if (array){
for (i = 0; i < ROW; ++i){ /*line 14*/
strcpy(array[i], "C!"); /*line 15*/
printf("%s\n", array[i]);
}
}
free(array);

return 0;
}
For more flexible approaches I suggest you read question 6.16 of the
comp.lang.c FAQ.
--
Flash Gordon
Sep 3 '06 #5

Coos Haak wrote:
Op 3 Sep 2006 10:28:48 -0700 schreef bw*****@yahoo.com:
lovecreatesbea...@gmail.com wrote:
strcpy(array[i], "C!"); /*line 15*/
printf("%s\n", array[i]);
strcpy doesn't nul terminate, so your call to printf will fault.

strcpy does, memcpy doesn't.
printf won't fail here.
You mis-read my comment. The OP only allocated array[0], so the
designation
array[1] through array[3] has not be allocated. Therefore, when you
strcpy, there is no way you can nul terminate since the designation is
smaller than the string being copied.

Sep 3 '06 #6

Here's one that will work since I have allocated the array each
time through the for loop. And strcpy will nul terminate because
the destination is big enough to hold the nul terminator.

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

int
main(void) {

char *string[20];
int i;

for (i = 0; i < 4; i++) {
string[i] = calloc(6, sizeof(char));
strcpy(string[i], "hello");
printf("%s\n", string[i]);
}
for (i = 0; i < 4; i++) {
free(string[i]);
}
return 0;
}

Sep 3 '06 #7

Flash Gordon wrote:
lovecreatesbea...@gmail.com wrote:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define ROW 4
#define COL 3

int main(void){
char (*array)[COL];
int i;

array = malloc(ROW * sizeof *array);
if (array){
for (i = 0; i < ROW; ++i){ /*line 14*/
strcpy(array[i], "C!"); /*line 15*/
printf("%s\n", array[i]);
}
}
free(array);

return 0;
}

For more flexible approaches I suggest you read question 6.16 of the
comp.lang.c FAQ.
Isn't the approach in my code example flexible enough? Isn't it correct?

Sep 4 '06 #8
Isn't the approach in my code example flexible enough? Isn't it correct?

No, it's not. For one,

char (*array)[COL];

Is errorneous. It is different from:

char *array[COL];

You should know that [] precedes the * operator. Insted of creating an
array of pointers to characters, you created a pointer to an array of
characters. See the difference?

Vardhan

Sep 4 '06 #9
lovecreatesbea...@gmail.com wrote:
This code snippet is an exercise on allocating two dimension array
dynamically. Though this one is trivial, is it a correct one?
Yes, its a 2 dimensional storage used for holding a 1 dimensional array
of C strings, being filled then output one at a time.
Furthermore, when I tried to make these changes to the original
example:

for (i = 0; i < ROW + 2; ++i){ /*line 14*/
strcpy(array[i], "C! C!"); /*line 15*/

Apparently, the modified code wrote to the memory unit outside the
allocated array, but the program ran well and there was no Segmentation
fault. Thank you.
Yes, this is called a buffer overflow. array is defined for ROW (== 4)
rows only, not ROW+2 rows. Furthermore each row can hold at most 3
characters, even though storing "C! C!" requires 6 characters. You can
read more about this condition here:

http://en.wikipedia.org/wiki/Buffer_overflow

Just because there happened to be valid memory past the end of your
well defined objects doesn't mean that accessing them is valid. The
lack of a Segmentation fault is not proof of correctness. (In fact
more buffer overflows in real world programs do not lead to immediate
Segmentation Faults.)
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define ROW 4
#define COL 3

int main(void){
char (*array)[COL];
int i;

array = malloc(ROW * sizeof *array);
if (array){
for (i = 0; i < ROW; ++i){ /*line 14*/
strcpy(array[i], "C!"); /*line 15*/
printf("%s\n", array[i]);
}
}
free(array);

return 0;
}
--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/

Sep 4 '06 #10

bw*****@yahoo.com wrote:
You mis-read my comment. The OP only allocated array[0], so the
designation
array[1] through array[3] has not be allocated. Therefore, when you
strcpy, there is no way you can nul terminate since the designation is
smaller than the string being copied.
You did not quote the enough related code of mine. I quote it below
with a change of locating the free invoke inside the if statement. In
my original allocation for the two dimensional array:

sizeof *array == COL * sizeof (char),
it's enough for holding a single element array[i];

ROW * sizeof *array == ROW * COL * sizeof (char),
this is the amount of the space for ROW rows of array[i].

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

#define ROW 4
#define COL 3

int main(void){
char (*array)[COL];
int i;

array = malloc(ROW * sizeof *array);
if (array){
for (i = 0; i < ROW; ++i){
strcpy(array[i], "C!");
printf("%s\n", array[i]);
}
free(array);
}

return 0;
}

Sep 4 '06 #11
lovecreatesbea...@gmail.com wrote:
bw*****@yahoo.com wrote:
You mis-read my comment. The OP only allocated array[0], so the
designation
array[1] through array[3] has not be allocated. Therefore, when you
strcpy, there is no way you can nul terminate since the designation is
smaller than the string being copied.

You did not quote the enough related code of mine. I quote it below
with a change of locating the free invoke inside the if statement. In
my original allocation for the two dimensional array:

sizeof *array == COL * sizeof (char),
it's enough for holding a single element array[i];

ROW * sizeof *array == ROW * COL * sizeof (char),
this is the amount of the space for ROW rows of array[i].
The proper size of memory has been allocated, and then I can access the
elements one by one. This is similar to what you can do with a dynamic
one dimensional array.

int *dynarray;
dynarray = malloc(10 * sizeof(int));
dynarray[0] = 0;
...
dynarray[9] = 0;
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define ROW 4
#define COL 3

int main(void){
char (*array)[COL];
int i;

array = malloc(ROW * sizeof *array);
if (array){
for (i = 0; i < ROW; ++i){
strcpy(array[i], "C!");
printf("%s\n", array[i]);
}
free(array);
}

return 0;
}
Sep 4 '06 #12
lovecreatesbea...@gmail.com wrote:
Flash Gordon wrote:
>lovecreatesbea...@gmail.com wrote:
<snip attempt at multi-dimensional array>
>For more flexible approaches I suggest you read question 6.16 of the
comp.lang.c FAQ.

Isn't the approach in my code example flexible enough? Isn't it correct?
Have you read the FAQ question I pointed you at? What have you failed to
understand in the answer it provides? I'm not going to bother rehashing
what is explained so well there when you seem not to have bothered to
read it.
--
Flash Gordon
Sep 4 '06 #13
Flash Gordon wrote:
lovecreatesbea...@gmail.com wrote:
Flash Gordon wrote:
lovecreatesbea...@gmail.com wrote:

<snip attempt at multi-dimensional array>
For more flexible approaches I suggest you read question 6.16 of the
comp.lang.c FAQ.
Isn't the approach in my code example flexible enough? Isn't it correct?

Have you read the FAQ question I pointed you at? What have you failed to
understand in the answer it provides? I'm not going to bother rehashing
what is explained so well there when you seem not to have bothered to
read it.
Hello, Mr. Gordon, Thank you. Is my original code correct?

That faq list is very good. I read it frequently and have made a local
copy by wget tool. Thank the author and others. It mentions:

"Yet another option is to use pointers to arrays:

int (*array4)[NCOLUMNS] = malloc(nrows * sizeof(*array4));"

This is the method I used in my code example, right?

Sep 4 '06 #14
Op 3 Sep 2006 16:17:17 -0700 schreef bw*****@yahoo.com:
Coos Haak wrote:
>Op 3 Sep 2006 10:28:48 -0700 schreef bw*****@yahoo.com:
>>lovecreatesbea...@gmail.com wrote:

strcpy(array[i], "C!"); /*line 15*/
printf("%s\n", array[i]);

strcpy doesn't nul terminate, so your call to printf will fault.

strcpy does, memcpy doesn't.
printf won't fail here.

You mis-read my comment. The OP only allocated array[0], so the
designation
array[1] through array[3] has not be allocated. Therefore, when you
strcpy, there is no way you can nul terminate since the designation is
smaller than the string being copied.
You write nonsense here, strcpy _always_ terminates with a null, even if
the string to copy has zero length. memcpy won't copy anything in this
case. The allocation may have been bad, but that is not my point.
--
Coos
Sep 4 '06 #15

Coos Haak wrote:
You mis-read my comment. The OP only allocated array[0], so the
designation
array[1] through array[3] has not be allocated. Therefore, when you
strcpy, there is no way you can nul terminate since the designation is
smaller than the string being copied.

You write nonsense here, strcpy _always_ terminates with a null, even if
the string to copy has zero length. memcpy won't copy anything in this
case. The allocation may have been bad, but that is not my point.
The function strcpy will attempt to nul terminate, but if the space
isn't big enough,
it might seg fault. I am not arguing that strcpy does not nul
terminate. I am
saying that in the OP's code there is no way for strcpy to nul
terminate because
it does not have any allocated space to write to.

Sep 4 '06 #16
lovecreatesbea...@gmail.com wrote:
Flash Gordon wrote:
>lovecreatesbea...@gmail.com wrote:
>>Flash Gordon wrote:
lovecreatesbea...@gmail.com wrote:
<snip attempt at multi-dimensional array>
>>>For more flexible approaches I suggest you read question 6.16 of the
comp.lang.c FAQ.
Isn't the approach in my code example flexible enough? Isn't it correct?
Have you read the FAQ question I pointed you at? What have you failed to
understand in the answer it provides? I'm not going to bother rehashing
what is explained so well there when you seem not to have bothered to
read it.

Hello, Mr. Gordon, Thank you. Is my original code correct?
I can't remember your original code. However, if I pointed out no errors
in it then I probably did not spot any.
That faq list is very good. I read it frequently and have made a local
copy by wget tool. Thank the author and others. It mentions:
OK, had you said that you had read it I would not have commented.
"Yet another option is to use pointers to arrays:

int (*array4)[NCOLUMNS] = malloc(nrows * sizeof(*array4));"

This is the method I used in my code example, right?
If that is the method you used, then yes it is valid. However, it is
less flexible than the other methods because you have to determine at
compile time the number of columns instead of being able to set it at
run time. Which methods are flexible enough depends on the exact
requirements and I can no longer remember what the OPs exact
requirements where.
--
Flash Gordon.
Sep 4 '06 #17

lovecreatesbea...@gmail.com wrote:
That faq list is very good. I read it frequently and have made a local
copy by wget tool. Thank the author and others. It mentions:

"Yet another option is to use pointers to arrays:

int (*array4)[NCOLUMNS] = malloc(nrows * sizeof(*array4));"

This is the method I used in my code example, right?
Nope. Look at that code.

Now, look at your code. How many integers in the above code can be
written per row and why? Where are you allocating space for the
characters you want to string copy in your code? How do you increase or
decrease the number of characters you want to allocate in your code?
How do you access the beginning of each string after you have string
copied it? I suggest drawing it out.

Here's a refresher on pointers for you:

http://cslibrary.stanford.edu/102/

Sep 4 '06 #18
On 3 Sep 2006 16:17:17 -0700, "bw*****@yahoo.com" <bw*****@yahoo.com>
wrote:
>
Coos Haak wrote:
>Op 3 Sep 2006 10:28:48 -0700 schreef bw*****@yahoo.com:
lovecreatesbea...@gmail.com wrote:

strcpy(array[i], "C!"); /*line 15*/
printf("%s\n", array[i]);

strcpy doesn't nul terminate, so your call to printf will fault.

strcpy does, memcpy doesn't.
printf won't fail here.

You mis-read my comment. The OP only allocated array[0], so the
designation
array[1] through array[3] has not be allocated. Therefore, when you
strcpy, there is no way you can nul terminate since the designation is
smaller than the string being copied.
No, it is you who misread the original code. The object named array
is a pointer to an array of three char. It is initialized to point to
a dynamically allocated area of memory which has room for four such
arrays.

The expression array[i] is the i-th array in the allocated memory. In
the context in which it is used, it evaluates to the address of
array[i][0] with type pointer to char. Since strcpy is copying only
three characters, they will fit it array[i] and both strcpy and printf
will behave.
Remove del for email
Sep 4 '06 #19
On 3 Sep 2006 16:36:05 -0700, "bw*****@yahoo.com" <bw*****@yahoo.com>
wrote:
>
Here's one that will work since I have allocated the array each
It would be nice if you quoted enough of the original thread to
indicate one what.
>time through the for loop. And strcpy will nul terminate because
the destination is big enough to hold the nul terminator.
Unless you invoke undefined behavior, strcpy will always nul
terminate.
>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int
main(void) {

char *string[20];
Why 20 when you only use 4?
> int i;

for (i = 0; i < 4; i++) {
string[i] = calloc(6, sizeof(char));
Why calloc when you immediately copy a string into the allocated
memory?

sizeof(char) is always 1.
> strcpy(string[i], "hello");
printf("%s\n", string[i]);
}
for (i = 0; i < 4; i++) {
free(string[i]);
}
return 0;
}

Remove del for email
Sep 4 '06 #20
On 3 Sep 2006 19:42:56 -0700, ex*****@gmail.com wrote:
>Isn't the approach in my code example flexible enough? Isn't it correct?

No, it's not. For one,

char (*array)[COL];

Is errorneous. It is different from:
His definition is not erroneous. He defines a pointer to an array and
uses it to reference the arrays it points to.
>
char *array[COL];

You should know that [] precedes the * operator. Insted of creating an
array of pointers to characters, you created a pointer to an array of
characters. See the difference?
While what you say is true, it has nothing to do with his code.
Remove del for email
Sep 4 '06 #21
On 3 Sep 2006 10:02:11 -0700, "lovecreatesbea...@gmail.com"
<lo***************@gmail.comwrote:
>This code snippet is an exercise on allocating two dimension array
dynamically. Though this one is trivial, is it a correct one?
Furthermore, when I tried to make these changes to the original
example:

for (i = 0; i < ROW + 2; ++i){ /*line 14*/
strcpy(array[i], "C! C!"); /*line 15*/

Apparently, the modified code wrote to the memory unit outside the
allocated array, but the program ran well and there was no Segmentation
fault. Thank you.
snip code

One of the unluckiest manifestations of undefined behavior is to
appear to work as intended.
Remove del for email
Sep 4 '06 #22

Let me clarify what I had written before. I had said that strcpy would
not nul terminate. Now, the fuction in theory should nul terminate.
This is not true if the space being written to is smaller. The same
holds true for strncpy.

Here's some example code, where strcpy does not nul terminate. I have
left out the test for calloc's (replaced the OP's malloc) success, and
I have left out the free'ing as the OP had done in their code.

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

#define COL 4
#define ROW 4

int
main(void) {

int i;
char (*string)[COL] = calloc(ROW, sizeof *string);

for (i = 0; i < ROW; i++) {
strcpy(string[i], "hello");
printf("%s\n", string[i]);
}
exit(EXIT_SUCCESS);
}

If I run this, it will print out hello four times. But that doesn't
mean it works. COL can only hold 3 characters plus a nul per row.

So when I run this through gdb, I see:

Breakpoint 1 at 0x4008ce: file string.c, line 20.
(gdb) run
Starting program: /home/user/string
hello
hello
hello
hello

Breakpoint 1, main () at string.c:20
20 exit(EXIT_SUCCESS);
(gdb) p *string
$1 = "hell"
(gdb) p/x string[0]
$2 = {0x68, 0x65, 0x6c, 0x6c}
(gdb)

As you can see, there is no nul terminator. The space was only large
enough to hold 4 characters. The remaining characters overwrote the
buffer space. But the program still appeared to work as seen by the
hello's printing.

I hope this explanation is better than just saying that strcpy does not
nul terminate. The changes suggested in the OP's message would write
to unallocated space. The for loop would try to strcpy to ROW's that
haven't been allocated.

Sep 4 '06 #23
"bw*****@yahoo.com" <bw*****@yahoo.comwrote:
Coos Haak wrote:
You mis-read my comment. The OP only allocated array[0], so the
designation
array[1] through array[3] has not be allocated. Therefore, when you
strcpy, there is no way you can nul terminate since the designation is
smaller than the string being copied.
You write nonsense here, strcpy _always_ terminates with a null, even if
the string to copy has zero length. memcpy won't copy anything in this
case. The allocation may have been bad, but that is not my point.

The function strcpy will attempt to nul terminate, but if the space
isn't big enough, it might seg fault.
The same is true for any other character that strcpy() writes. If you
wanted to say that strcpy() has undefined behaviour if it is made to
write to memory that has not been properly allocated, that's what you
should have written. This claptrap about null termination is just that:
balderdash.

Richard
Sep 5 '06 #24
On 4 Sep 2006 16:45:19 -0700, "bw*****@yahoo.com" <bw*****@yahoo.com>
wrote:
>
Let me clarify what I had written before. I had said that strcpy would
not nul terminate. Now, the fuction in theory should nul terminate.
This is not true if the space being written to is smaller. The same
holds true for strncpy.
If you use any function to move data into a space too small for that
data, you invoke undefined behavior.
>
Here's some example code, where strcpy does not nul terminate. I have
left out the test for calloc's (replaced the OP's malloc) success, and
I have left out the free'ing as the OP had done in their code.

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

#define COL 4
#define ROW 4

int
main(void) {

int i;
char (*string)[COL] = calloc(ROW, sizeof *string);

for (i = 0; i < ROW; i++) {
strcpy(string[i], "hello");
printf("%s\n", string[i]);
}
exit(EXIT_SUCCESS);
}

If I run this, it will print out hello four times. But that doesn't
If you run this, you invoke undefined behavior. It doesn't matter
what the results are on your system because we are no longer in the
realm of C.
>mean it works. COL can only hold 3 characters plus a nul per row.
You meant string, not COL. In this particular case, string points to
an allocated block of memory which is 16 bytes. When i is 0, the
strcpy and the printf will reference bytes 0 through 5, When i is 1,
they use bytes 4 through 9. When i is 2, They use bytes 8 through 13.
All these operations are well defined. When i is 3, they attempt to
use bytes 12 through 17. This is undefined behavior.

Remove del for email
Sep 5 '06 #25
In article <11**********************@m79g2000cwm.googlegroups .com>
bw*****@yahoo.com <bw*****@yahoo.comwrote:
>Let me clarify what I had written before. I had said that strcpy would
not nul terminate. Now, the fuction in theory should nul terminate.
This is not true if the space being written to is smaller.
Well, yes and no:

char buf[4]; /* can hold "abc" */

strcpy(buf, "supercalifragialisticexpialidocious"); /* ERROR */

The effect of this call to strcpy() is undefined, because the
call "wants" to write 36 "C bytes" ("char"s) into a four-character
array.

In practice, on most real machines, it really *does* write all 36
bytes (35 letters plus '\0' byte) into the four-character array,
overwriting 32 other bytes. Subsequent behavior depends on what
was in those "other" bytes, and how important they were. Of course,
since the behavior is undefined, the C Standards say nothing about
what has to happen, so whatever *does* happen is the programmer's
problem, not the implementation's.

In the case when what *does* happen is "the program continues to
run", if you stop the program with some external agent and inspect
the array named "buf", it is true that it will not hold a '\0'-terminated
C string. Instead, it will hold the first four characters of the
copied string -- in this case 's', 'u', 'p', and 'e'. This is
precisely what you see when you use your debugger:

[I need to quote the entire code, or change it; for time reasons on
my part, I will just quote]
>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <err.h>

#define COL 4
#define ROW 4

int
main(void) {

int i;
char (*string)[COL] = calloc(ROW, sizeof *string);

for (i = 0; i < ROW; i++) {
strcpy(string[i], "hello");
printf("%s\n", string[i]);
}
exit(EXIT_SUCCESS);
}

If I run this, it will print out hello four times. But that doesn't
mean it works. COL can only hold 3 characters plus a nul per row.

So when I run this through gdb, I see:

Breakpoint 1 at 0x4008ce: file string.c, line 20.
(gdb) run
Starting program: /home/user/string
hello
hello
hello
hello

Breakpoint 1, main () at string.c:20
20 exit(EXIT_SUCCESS);
(gdb) p *string
$1 = "hell"
(gdb) p/x string[0]
$2 = {0x68, 0x65, 0x6c, 0x6c}
(gdb)

As you can see, there is no nul terminator. The space was only large
enough to hold 4 characters. The remaining characters overwrote the
buffer space. But the program still appeared to work as seen by the
hello's printing.
And in fact, what happened on your machine (which I can predict
due to my Amazing Psychic Abilities :-) ) is that calloc(4,4)
actually obtained more than 16 bytes, and each of the strcpy()
calls put six bytes into the corresponding four-byte region, with
the "extra two bytes" writing over the next array entry (when i
\elem {0,1,2}) or some of the "spare" bytes calloc() got (when
i==3). The printf() calls accessed all six bytes of each four-byte
region (including the two that extend past the region). The
debugger, however, is much smarter than the C runtime library, and
even if you print string[3], it will only access the "proper four"
of the six bytes written into corresponding four-byte region.

Note also that:

char buf16[16];
strcpy(&buf16[0], "hello");
strcpy(&buf16[4], "hello");

is well-defined, and puts the string "hellhello" into the 16-byte
buffer "buf16". The first strcpy() does in fact write a complete
string; the second strcpy() then overwrites part of the first,
writing a new complete string that makes the previous string
longer.

If you then do:

printf("%.4s\n", &buf[0]);

the output will be "hell\n", not "hellhello\n" -- and gdb essentially
does just this.
>I hope this explanation is better than just saying that strcpy does not
nul terminate.
It just goes to show that, when there is undefined behavior,
*anything* can happen, including "it seems to work, but the debugger
-- which does different things from the C library -- shows different
results".
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Sep 5 '06 #26

Barry Schwarz wrote:
You meant string, not COL. In this particular case, string points to
an allocated block of memory which is 16 bytes. When i is 0, the
strcpy and the printf will reference bytes 0 through 5, When i is 1,
they use bytes 4 through 9. When i is 2, They use bytes 8 through 13.
All these operations are well defined. When i is 3, they attempt to
use bytes 12 through 17. This is undefined behavior.
You are explanation is far better than mine. Is the right answer all
ways undefined behavior when the program is written in a way, where the
C programming language is no longer clear as to what happens?

Sep 6 '06 #27
On 6 Sep 2006 09:33:47 -0700, "bw*****@yahoo.com" <bw*****@yahoo.com>
wrote:
>
Barry Schwarz wrote:
>You meant string, not COL. In this particular case, string points to
an allocated block of memory which is 16 bytes. When i is 0, the
strcpy and the printf will reference bytes 0 through 5, When i is 1,
they use bytes 4 through 9. When i is 2, They use bytes 8 through 13.
All these operations are well defined. When i is 3, they attempt to
use bytes 12 through 17. This is undefined behavior.

You are explanation is far better than mine. Is the right answer all
ways undefined behavior when the program is written in a way, where the
C programming language is no longer clear as to what happens?
The standard identifies several different types of behavior: defined,
unspecified, undefined, implementation defined, and possibly others.

Clarity on the other hand is pretty subjective, confirmed by many of
the wandering threads in this group.
Remove del for email
Sep 7 '06 #28

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: nkw | last post by:
Hi, I'm new to C and I'm stuck in working out the logic code for a cyclic array. I have an array of 5 cells, starting at index cell 0 and last cell is 4. ie 0 1 2 3 4 0 1 ..... and so on
19
by: Sameer | last post by:
Hi friends, I am using Mandriva Linux 9.2 and gcc. My source code is, int chunkin ; //no error int i ; for (i=0;i<7225;i++) { chunkin = somedata ;
1
by: manoharyes | last post by:
hi experts, i am getting a segmentation fault error in this piece of code.. node.c has some contents. my intension is to read the contents of a file into an array then.. dynamically allocate...
3
by: madunix | last post by:
My Server is suffering bad lag (High Utlization) I am running on that server Oracle10g with apache_1.3.35/ php-4.4.2 Web visitors retrieve data from the web by php calls through oci cobnnection...
4
by: hobbes992 | last post by:
Howdy folks, I've been working on a c project, compiling using gcc, and I've reached a problem. The assignment requires creation of a two-level directory file system. No files have to be added or...
1
by: Peterwkc | last post by:
Hello all expert, i have two program which make me desperate bu after i have noticed the forum, my future is become brightness back. By the way, my problem is like this i the first program was...
27
by: Jess | last post by:
Hello, the following code failed with "segmentation fault". Could someone tell me why it failed please? Thanks! #include<iostream> #include<string> #include<cstring> #include<cstddef> using...
14
by: ptq2238 | last post by:
Hi, I'm getting confused with arrays and hope someone can shed light on my code. I wrote this to try and learn about files and arrays as I thought if I could grab each element and place them into...
3
by: Anna | last post by:
Could you please help me? I got a segmentation fault message while trying to assign a pointer = pointer like this: bufferlist=(buffer_t*)buffernew; What's the error by doing this? Here is the...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.