This is how the struct looks like for reference:
struct thread_data {
struct ringbuf_t *rb;
char *file_name;
};
I need to take command line arguments and store it inside struct member variables for each thread_data
element in the threads
array, like so:
for (int index = optind; index < argc; index ) {
threads[length].rb = rb;
memmove(&threads[length].file_name, &argv[index], strlen(argv[index]));
strcpy(threads[length].file_name, argv[index]);
length;
}
Prevously used memcpy
and it worked when I printed the variable. However, Valgrind is giving me this:
==465645== Source and destination overlap in strcpy(0x1fff000b54, 0x1fff000b54)
==465645== at 0x4C3C180: strcpy (vg_replace_strmem.c:523)
==465645== by 0x400F85: main (bytemincer.c:55)
So I used memmove
and I still got the same Valgrind result. Any solution for this?
CodePudding user response:
This is what you want to end up with:
(I'm using "fn" instead of "file_name" in the post.)
*(argv[0]) @ 0x2000
--- --- - - ---
--------------->| | | … | 0 |
argv @ 0x1000 | --- --- - - ---
--------------- |
| 0x2000 ------- *(argv[1]) @ 0x2100
--------------- --- --- - - ---
| 0x2100 ----------- ----------->| | | … | 0 |
--------------- | --- --- - - ---
| 0x2200 -----------)----
--------------- | | *(argv[2]) @ 0x2200
| ⋮ | | | --- --- - - ---
| ------->| | | … | 0 |
rb @ 0x3000 | | --- --- - - ---
--------------- | |
| 0x4000 ------- | | *rb @ 0x4000
--------------- | | | ---------------
---)---)------->| |
threads @ 0x5000 | | | ---------------
--------------- | | |
| ----------- | | | |
|rb| 0x4000 -------- | |
| ----------- | | | |
|fn| 0x2100 --------)--- |
| ----------- | | |
--------------- | |
| ----------- | | |
|rb| 0x4000 -------- |
| ----------- | |
|fn| 0x2200 ----------------
| ----------- |
---------------
| ⋮ |
(This assumes threads
is an array rather than a pointer to an array. This doesn't affect the rest of the post.)
All addresses are made up, of course. But you can see how more than once variable have the same address for value. Because it's perfectly fine to have multiple pointers point to the same memory block. All we need to do is copy the pointer (the address).
To copy a pointer, all you need to do is
dst = src;
So all you need is
threads[length].rb = rb;
threads[length].fn = argv[index];
While
memmove(&threads[length].rb, &rb, sizeof(threads[length].rb));
memmove(&threads[length].fn, &argv[index], sizeof(threads[length].fn));
and
memmove(&threads[length].rb, &rb, sizeof(rb));
memmove(&threads[length].fn, &argv[index], sizeof(argv[index]));
are equivalent to the assignments, it doesn't make sense to do something that complicated:
(Note the use of sizeof(argv[index])
rather than strlen(argv[index])
. It's the pointer we're copying, so we need the size of the pointer.)
The warning came from trying to copy the string that's in the buffer at 0x2100 into the buffer at 0x2100. Remember that threads[length].fn
and argv[index]
both have the same value (address) after the memmove
.