@Salem I don't understand what's wrong with memcpy and sizeof.
@Salem I don't understand what's wrong with memcpy and sizeof.
Simple study aid.
Code:#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct { int arr[10]; } foo_t; void show ( foo_t *p ) { for ( int i = 0 ; i < 10 ; i++ ) { printf("%d ", p->arr[i]); } printf("\n"); } int main ( ) { foo_t original = { { 1,2,3,4,5,6,7,8,9,10 } }; show(&original); foo_t *p = malloc(sizeof(*p)); memcpy(p,&original,sizeof(p)); //!! oops, size of pointer show(p); // garbage memcpy(p,&original,sizeof(*p)); //!! better, size of thing being pointed to show(p); // better *p = original; // yes, struct assignment works too show(p); return 0; } $ gcc -Wall foo.c foo.c: In function ‘main’: foo.c:21:28: warning: argument to ‘sizeof’ in ‘memcpy’ call is the same expression as the destination; did you mean to dereference it? [-Wsizeof-pointer-memaccess] memcpy(p,&original,sizeof(p)); ^ $ ./a.out 1 2 3 4 5 6 7 8 9 10 1 2 0 0 0 0 0 0 0 0 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 $
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
@Salem Thanks for the explanation, I understand now. I just have updated my code ([C] buggy output - Pastebin.com), however the second inode output is still buggy. Can you tell me what is wrong with the updated code?
Yes, fix this valgrind error (which repeats ad nauseam)
Code:$ gcc -Wall main.c $ gcc -Wall -g main.c $ valgrind ./a.out ==10664== Memcheck, a memory error detector ==10664== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. ==10664== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info ==10664== Command: ./a.out ==10664== ==10664== Invalid write of size 1 ==10664== at 0x4C3106F: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==10664== by 0x401185: ffnode (main.c:306) ==10664== by 0x4019C4: syntax (main.c:443) ==10664== by 0x401AF1: main (main.c:478) ==10664== Address 0x5203165 is 0 bytes after a block of size 5 alloc'd ==10664== at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==10664== by 0x40198C: syntax (main.c:440) ==10664== by 0x401AF1: main (main.c:478)ffnode also (ab)uses pt->value as well - should it?Code:pt->value = calloc(strlen(S)+1, sizeof(char)); strcpy(pt->value, S); err = ffnode(pt, lex);
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
@SalemYes, definitely, it should. I don't think this is affecting pt->value at all.ffnode also (ab)uses pt->value as well - should it?
==10664== Invalid write of size 1
==10664== at 0x4C3106F: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10664== by 0x401185: ffnode (main.c:306)
==10664== by 0x4019C4: syntax (main.c:443)
==10664== by 0x401AF1: main (main.c:478)
==10664== Address 0x5203165 is 0 bytes after a block of size 5 alloc'd
==10664== at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10664== by 0x40198C: syntax (main.c:440)
==10664== by 0x401AF1: main (main.c:478)
I don't know why valgrind is generating these leak informations, though ..
Can you see it yet?
You allocated 5 bytes.Code:$ gcc -Wall -g main.c $ gdb ./a.out Reading symbols from ./a.out...done. (gdb) b 306 Breakpoint 1 at 0x40115c: file main.c, line 306. (gdb) run Starting program: /home/sc/Documents/a.out Breakpoint 1, ffnode (inode=0x604080, lex=0x604010 "D AO IW D SO IW SO D OW OW") at main.c:306 306 strcpy(inode->value, tokens[i]); (gdb) print inode->value $1 = 0x6040b0 "MOPN" (gdb) print tokens[i] $2 = 0x604480 "OPNP1" (gdb) up #1 0x00000000004019c5 in syntax (pt=0x604080, lex=0x604010 "D AO IW D SO IW SO D OW OW") at main.c:443 443 err = ffnode(pt, lex); (gdb) print S $3 = 0x401cf5 "MOPN" (gdb) print strlen(S)+1 $4 = 5
OPNP1 takes 6
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
@Salem I missed that, thanks for pointing that out. Now, I just have updated my code, and everything works correctly. But, after changing lex to another example "SO SO D AO IW D SO IW SO D OW OW" (to check the reliability of the program, see [C] bug occurs after changing lex - Pastebin.com), I've got the program crashing and throwing SIGSEGV.
Well I've shown you how to use gdb, so it's time to see what you can do.
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
@Salem Ok, I solved the problem by usinginstead ofint cl=inode->childlen; for (int i=0; i<cl; i++). Thanks for your help.for (int i=0; i<childlen; i++)