1

I'm beginner with C and I'm trying to create an array of strings saved like this:

[1][firststring]

[2][secondstring]

[2][thirdstring] .

.

.

My implementation looks like:

int counter = 0;
char for_pole[50][50];
strcpy(for_pole[counter][50],"hello");
counter++;
//then i want to print it:
printf("my string: %s", for_pole[0][50]); //prints out first string
printf("my string: %s", for_pole[1][50]); //...and second one

but returns segmentation fault.

Should i use some dynamic allocation of memory? As I've told I'm novice, so sorry for bad question.

jon.e
  • 73
  • 8
  • 2
    Doesn't your compiler tell you that the first parameter to `strcpy()` is incompatible. – Iharob Al Asimi Jan 25 '16 at 23:59
  • 3
    index 50 does not exist in an array of 50 elements. – tkausl Jan 26 '16 at 00:01
  • `for_pole[counter][50]` is the 51st char in `for_pole[counter]`, which is the `counter`'th string (starting from 0). So it's the 51st char of the `counter`th (starting from 0) string. As opposed to being the whole string. – user253751 Jan 26 '16 at 00:53

5 Answers5

1

I do not see where in your code there is the second string. I see only one string `"hello".

You can write for example the following way

int counter = 0;
char for_pole[50][50];
strcpy(for_pole[counter],"hello");
counter++;
strcpy(for_pole[counter],"world");

//then i want to print it:
printf("my string: %s\n", for_pole[0]); //prints out first string
printf("my string: %s\n", for_pole[1]); //...and second one

As for this expression

for_pole[counter][50]

then 1) index 50 is outside the array because the valid range of indices is 0 - 49 and 2) it has type char instead of to be an array or a pointer to char that is required by function strcpy or by the format specifier %s. of function printf.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
1

When you write

strcpy(for_pole[counter][50],"hello");

You're writing the string "hello" to a char. Moreover, it is on the position 50 of an array that goes from 0 to 49.

you should change it to

strcpy(for_pole[counter],"hello");

because "for_pole[i]" is the i-th string and "for_pole[i][j]" is the j-th character of that string.

Similarly that printf should be

printf("my string: %s", for_pole[0]);

I would add a '\n' to get things a little bit more organized

Finally, the code would be like this

int counter = 0;
char for_pole[50][50];
strcpy(for_pole[counter],"hello");
counter++;

printf("my string: %s\n", for_pole[0]); //prints out first string
printf("my string: %s\n", for_pole[1]); //prints out second string
Khanis Rok
  • 617
  • 6
  • 12
0

initialize for_pole variable with zero.

char for_pole[50][50] = {0,};
0

Jon.e, there are some reasons for SEGFAULT. Even when there is no bug at all, but rather there are a lack of memory.

Some guys tell you, to pay attention to compiler message and warning, yes, but that's just a part of story.

Related to SEGFAULT there are the following most notable kinds of SEGFAULTS, that I can tell you by my own experience:

1. You are trying to access to indices which do not exist.

Array has the size, exactly same size which you have specified while declaring an array. Review this code:

/* "Array out of bounds" error 
       valid indices for array foo
       are 0, 1, ... 999 */
  int foo[1000];
  for (int i = 0; i <= 1000 ; i++) 
    foo[i] = i; 

Here we have one illegal access to an index which does not exist.

2. You are trying to access to the value which does not exist.

In this case memory exists but the value...

/* Illegal memory access if value of n is 
       not in the range 0, 1, ... 999 */
  int n;
  int foo[1000];
  for (int i = 0; i < n ; i++) 
    foo[i] = i;

This is also one of the most common pitfalls. This pitfall is so fundamental, even experienced developers sometime make such mistake. The problem is in uninitialized memory for variable n. Initialization is process of putting value of the variable its first value, If you want, we can say that it's process of losing virginity of the variable. There are very chaotic rule of when variable is initialized and when - not. To complex for remembering. Just always initialize variables.

3. You are trying to access to the memory via pointers.

And that pointer does not point anywhere. You are trying to read something from NOWHERE? It does not make sense, does it?

/* Illegal memory access because no memory
       is allocated for foo2 */
  float  *foo, *foo2; 
  foo = (float*)malloc(1000);
  foo2[0] = 1.0;

What happens, if you forget to initialize variable( 2-nd ) or pointer (3-rd case). The answer is broad: from nothing to catastrophe.

Why so? Because memory is the something which has been used by a lot of applications, and it's shared between hundreds of thousands applications running on a computer. So when you create a variable it creates the segment in the memory for that variables, but does not clean that memory (to be precise, in some cases it has been nulled, in others - not) Just assume that is never cleared. So in such situations, no matter the problem caused by variable or by pointer (which is actually is a variable too, but that's another story), we say that, variable stores 'garbage'.

Note, it's not obvious, to find those kind of SEGFAULTS, sometimes it's almost impossible, so you must be ready for such situations, and should use debugger for example gdb, to eliminate the bug.

Also avoid such dummy errors, like. The practice with my students show that it's very very common error.

int n = 100;
int foo[n];

use instead

int foo[100]

or

const int n = 100;
int foo[n];

or

enum N { N = 100 };
int is[N];

Additional references: Can a const variable be used to declare the size of an array in C? https://kb.iu.edu/d/aqsj

Community
  • 1
  • 1
Nusrat Nuriyev
  • 1,134
  • 2
  • 13
  • 29
0

You misunderstand...

...how strings and array indexing work together. A string is an array of characters. For example this is a string:

char some_string[20] = "Hello";

And this is how you print it:

printf("%s\n", some_string);

And this is how you use strcpy() with it:

strcpy(some_string, "Goodbye");

And this is how you access the i-th character in the string:

/* Not compilable by itself; just an example. */
some_string[i]

Notice how the only time you used [...] was in declaring it and accessing a specific character in the array of characters. However, that is for a single string.

For an array of strings, you declare it as a 2-dimensional array of characters, just as you've done with for_pole:

/* An array of 50 strings, all of which can store a maximum of 49
 * characters, plus a null termination character for each string.
 */
char for_pole[50][50];

To use strcpy() with the counter-th string:

strcpy(for_pole[counter], "hello");

And to print the first (0-th) string:

printf("my string: %s", for_pole[0]);

And to print the i-th character of the first string:

printf("string[%d]: %c", i, for_pole[0][i]);

Again, notice how I didn't use [50] every time here. If you have a string, you access it using its name and each character using string[i]. If you have an array of strings, you access the array using its name and each string using array[i] notation. To access the j-th character of the i-th string in the array:

/* Not compilable by itself; just an example. */
array[i][j]

Why your version segfaults

You don't need to use [50] in every expression the way you do. Notice the last expression array[i][j] to access a single character. Since a character is represented by an integer value, the compiler will then convert that integer to a pointer where necessary.

This means that doing something like strcpy(for_pole[counter][50],"hello"); will try to copy the string "hello" to whatever memory address the compiler thinks the character for_pole[counter][50] holds. For example, if the character is the letter A, represented by the integer 65 on my system, then the program would try to copy all 6 bytes of the string "hello" to memory address 65. My program doesn't have permission to write to that memory address, so it segfaults. And that's the problem you are experiencing.

Community
  • 1
  • 1