2

first time poster here.

I'm trying to write a block of code in c that takes a struct with 5 different strings (each a max of 32 characters) that concatenates the whole lot into a single comma-separated string and writes it to a text file. I've done a similar thing using c++ and it's worked fine, the problem I'm having with my c version is, I think, in this part of the code...

char *out[256] = {(char*)malloc(sizeof(*out))};
int i;

*out = conc(v);

printf("%s\n", *out);

FILE *fp;
fp = fopen(fname, "w");

i = fprintf(fp, *out);

printf("i = %d\n", i);

fclose(fp);

I believe the problem is in the i = fprintf(fp, *out) line, whenever the total character count of out is over 25 characters the program crashes and dumps the following to the console...

*** glibc detected *** ./file2: free(): invalid next size (normal): 0x00000000011d5100 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x76d76)[0x7f62635f4d76]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x6c)[0x7f62635f9aac]
/lib/x86_64-linux-gnu/libc.so.6(fclose+0x14d)[0x7f62635e5ccd]
./file2[0x400f08]
./file2[0x400a95]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd)[0x7f626359cead]
./file2[0x400969]
======= Memory map: ========
00400000-00402000 r-xp 00000000 08:01 2099569                            /home/richard/Documents/C/file2
00601000-00602000 rw-p 00001000 08:01 2099569                            /home/richard/Documents/C/file2
011d5000-011f6000 rw-p 00000000 00:00 0                                  [heap]
7f625c000000-7f625c021000 rw-p 00000000 00:00 0 
7f625c021000-7f6260000000 ---p 00000000 00:00 0 
7f626357e000-7f62636fe000 r-xp 00000000 08:01 2883603                    /lib/x86_64-linux-gnu/libc-2.13.so
7f62636fe000-7f62638fe000 ---p 00180000 08:01 2883603                    /lib/x86_64-linux-gnu/libc-2.13.so
7f62638fe000-7f6263902000 r--p 00180000 08:01 2883603                    /lib/x86_64-linux-gnu/libc-2.13.so
7f6263902000-7f6263903000 rw-p 00184000 08:01 2883603                    /lib/x86_64-linux-gnu/libc-2.13.so
7f6263903000-7f6263908000 rw-p 00000000 00:00 0 
7f6263908000-7f626391d000 r-xp 00000000 08:01 2883588                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7f626391d000-7f6263b1d000 ---p 00015000 08:01 2883588                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7f6263b1d000-7f6263b1e000 rw-p 00015000 08:01 2883588                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7f6263b1e000-7f6263b9f000 r-xp 00000000 08:01 2883600                    /lib/x86_64-linux-gnu/libm-2.13.so
7f6263b9f000-7f6263d9e000 ---p 00081000 08:01 2883600                    /lib/x86_64-linux-gnu/libm-2.13.so
7f6263d9e000-7f6263d9f000 r--p 00080000 08:01 2883600                    /lib/x86_64-linux-gnu/libm-2.13.so
7f6263d9f000-7f6263da0000 rw-p 00081000 08:01 2883600                    /lib/x86_64-linux-gnu/libm-2.13.so
7f6263da0000-7f6263e88000 r-xp 00000000 08:01 266029                     /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17
7f6263e88000-7f6264088000 ---p 000e8000 08:01 266029                     /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17
7f6264088000-7f6264090000 r--p 000e8000 08:01 266029                     /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17
7f6264090000-7f6264092000 rw-p 000f0000 08:01 266029                     /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17
7f6264092000-7f62640a7000 rw-p 00000000 00:00 0 
7f62640a7000-7f62640c7000 r-xp 00000000 08:01 2883606                    /lib/x86_64-linux-gnu/ld-2.13.so
7f62642ab000-7f62642b0000 rw-p 00000000 00:00 0 
7f62642c2000-7f62642c6000 rw-p 00000000 00:00 0 
7f62642c6000-7f62642c7000 r--p 0001f000 08:01 2883606                    /lib/x86_64-linux-gnu/ld-2.13.so
7f62642c7000-7f62642c8000 rw-p 00020000 08:01 2883606                    /lib/x86_64-linux-gnu/ld-2.13.so
7f62642c8000-7f62642c9000 rw-p 00000000 00:00 0 
7fff9a5f6000-7fff9a617000 rw-p 00000000 00:00 0                          [stack]
7fff9a761000-7fff9a762000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted

When the contents of out is less than 25 characters this works perfectly. I'm still reasonably new to c/c++ so I'm sure i'm doing something obviously stupid, just mot sure what it is.

This is running on Debian (7.3 I think, the latest version), I havent had the opportunity to try it on any other computer or OS.

I've had a bit of a poke around the internet to see if there's any way to set a buffer for fprintf, if there is I haven't been able to find it.

Thank you all for any help you may be able to give.

3
  • 1
    that code doesn't make a lot of sense.... Commented Dec 30, 2013 at 10:51
  • give the prototype of conc(v) Commented Dec 30, 2013 at 10:52
  • 1
    Heh, no the problem isn't a part of the code, it's the whole thing. Commented Dec 30, 2013 at 10:52

2 Answers 2

2

Analyzing only the first part of your code reveals some severe cavities:

char *out[256] = {(char*)malloc(sizeof(*out))};
// 'out' is an array of 256 pointers, all of which are NULL except for the first pointer (out[0]),
// which points to a piece of dynamically allocated memory with a size of 4 bytes (sizeof(char*)).

*out = conc(v);
// Now out[0] is pointing to somewhere else, so you've definitely got a memory
// leak because you will not be able to free what you have "malloc'ed" above...

printf("%s\n", *out);
// If out[0] is not pointing to a null-terminated string, then your program will most
// likely perform a memory access violation at this point, leading to an exception...
Sign up to request clarification or add additional context in comments.

6 Comments

printf("%s\n", *out); <= this line works, it prints the entire contents of out to stdout fine, it's only the fprintf command that crashes the program. With the fprintf line commented out of the above code it runs and displays the output to the console just as it should, with that line left in as long as the total length of out is less than 25 characters it works, it's only once it goes over that that it crashes. I know I'm using pointers where it's not necessary but the biggest hurdle I've had with c/c++ is getting my head around them so I try to use them whenever I can in my practice code.
If 'conc(v)' returns a pointer to a null-terminated string, then the call to 'printf' will work correctly (assuming that there are no '%' within that string). Since you did not provide any information on the function 'conc' and the argument 'v', I cannot relate to the result of 'printf' after executing '*out = conc(v)'. And in any case, the result of the call to 'printf' does not change the bugs mentioned above.
It's definitely null-terminated. v is just a struct with 5 strings and conc just concatenates them into one comma-separated string. The response below seems to have my code running ok so I might have to just try it on another machine and keep playing around with it, I guess it's the only way I'm going to learn. I'll definitely be modifying to rectify the errors you highlighted above (I did notice upon first try that it wouldn't let me free *out and I wasn't quite sure why), so thank you for those tips.
So I'm assuming that 'conc' returns the address of some struct, casted to char*, correct? If that's the case, then you might have a problem there too: if that struct is dynamically allocated, then you are not freeing it anywhere (at least not in the example you provided). Otherwise, you must declare it 'static' within the function 'conc' (or as a global variable, in which case, you have no need for the 'out variable). If you did not declare it as such, there's a good chance your that code will crash, as this struct is no longer "viable" by the time you're out of the 'conc' function.
And in any case, the 'malloc' at the beginning of your code is completely redundant.
|
0

Check this answer : https://stackoverflow.com/a/2018787/2549281 Looks like you miss a param in fprintf

fprintf(f, ": %s\n", str);

6 Comments

Thanks mate, I did forget to add the "%s". However, it still crashes in the exact same way.
did you manage to print into the file some "abcdcdd" string ? Try to localize the issue
Yes, as long as the contents of out is less than 25 characters it prints to file fine.
How do you concat the strings ? Your sure you don't add some junk that breaks the fprintf?
I tested on my machine it work fine. this is my conc: char* conc(char* a,char* b,char* c,char* v ) { char* out = malloc(sizeof(char)*255); strcat(out,a); strcat(out,b); strcat(out,c); strcat(out,v); return out; }
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.