C - disclosure problem
I have simplified the problem, which was trying to isolate the problem, but it doesn't help.
I have a 2 dimensional char array to represent memory. I want to pass a reference to this memory simulation to a function. In a function to check the contents of memory, I just want to iterate through memory and print the contents on each line.
The program prints the first line and then I get a seg error.
My program looks like this:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
void test_memory(char*** memory_ref) {
int i;
for(i = 0; i < 3; i++) {
printf("%s\n", *memory_ref[i]);
}
}
int main() {
char** memory;
int i;
memory = calloc(sizeof(char*), 20);
for(i = 0; i < 20; i++) {
memory[i] = calloc(sizeof(char), 33);
}
memory[0] = "Mem 0";
memory[1] = "Mem 1";
memory[2] = "Mem 2";
printf("memory[1] = %s\n", memory[1]);
test_memory(&memory);
return 0;
}
This gives me the result:
memory[1] = Mem 1
Mem 0
Segmentation fault
If I modify the program and create a local version of the memory in the function by dereferencing memory_ref, I get the correct output:
So:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
void test_memory(char*** memory_ref) {
char** memory = *memory_ref;
int i;
for(i = 0; i < 3; i++) {
printf("%s\n", memory[i]);
}
}
int main() {
char** memory;
int i;
memory = calloc(sizeof(char*), 20);
for(i = 0; i < 20; i++) {
memory[i] = calloc(sizeof(char), 33);
}
memory[0] = "Mem 0";
memory[1] = "Mem 1";
memory[2] = "Mem 2";
printf("memory[1] = %s\n", memory[1]);
test_memory(&memory);
return 0;
}
gives me the following output:
memory[1] = Mem 1
Mem 0
Mem 1
Mem 2
which is what I want, but making a local version of memory is useless because I need to be able to change the values of the original memory from a function, which I can only do by dereferencing the pointer to the original 2d char.
I don't understand why the second time I should get a seg error, and I would appreciate any advice.
Many thanks
Joe
a source to share
Try:
printf("%s\n", (*memory_ref)[i]);
The current version is equivalent to
*(*(memory_ref + i));
This is because the operator []
has higher precedence than dereference *
. This means that when i
greater than 0, you are trying to read memory after a char***
temporarymemory_ref
The second version is equal (*memory_ref)[i]
, which means you will be indexing the correct memory.
EDIT: The reason it works on the first iteration is this:
*(*(memory_ref + 0)) == *((*memory_ref) + 0)
a source to share
The quick fix is to use
printf("%s\n", (*memory_ref)[i]);
But I suspect you have a line problem
memory[0] = "Mem 0";
They do not copy the "Mem 0" string into your memory array. They make memory [i] point to a string.
You need to copy the data explicitly using strncpy
eg. char s = "Mem 0"; strncpy (memory 1 , s, max (strlen (s) + 1, 29)) // max 30 = (29 char + '\ 0' since this is the length of the string you have allocated - better #define this as a constant
a source to share