Reputation: 31
My first question here. I am using an array of pointers instead of a 2D array. Now, to display an element I can use *(arr[i]+j), where arr is the array i denotes the row and j denotes the column. However, when I try to assign a value to any element using the same notation the code stops working. I dont get a compilation error but when I run it it just stops working. Could anybody help me?
Here is my code
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
int i,j,k;
char temp2, temp, *arr[] = {
"Brinda Roy",
"Rakesh Bai",
"Neha Saxen",
"Ankit Jain"};
printf("%c",*(arr[3]+8));
for(i=0;i<4;i++){
for(j=0, k=9; j<=4, k>=5; j++, k--){
temp =*(arr[i]+j);
*(arr[i]+j)=*(arr[i]+k);
*(arr[i]+k)=temp;
}
}
printf("\nThe array is ");
for(i=0; i<4; i++){
printf("\n%s",arr[i]);
}
getch();
return 0;
}
Upvotes: 3
Views: 162
Reputation: 47770
You try to modify string literals. This is forbidden. Note that even though this is not enforced by the type system ("abc"
is not const char*
), modifying a character literal "abc"[1]='c'
leads to undefined behavior.
You have to move your data to a writable location. The easiest, though nonstandard way of doing this would be using the strdup
function:
for(i=0; i<4; i++)
arr[i]=strdup(arr[i]);
That will allocate memory on the heap for the string and copy the string to it. If you don't have the strdup
function, you have to implement it using malloc
, strlen
and memcpy
.
Note that as always with dynamically allocated memory, you have to free it; otherwise, you get a memory leak.
BTW the normal way to access both double pointer arrays and multidimensional arrays is arr[i][j]
.
Upvotes: 2
Reputation: 1599
You cannot modify the memory reserved this way:
{"Brinda Roy",
"Rakesh Bai",
"Neha Saxen",
"Ankit Jain"};
When you define a char* this way, it is only read memory.
Upvotes: 1
Reputation: 104120
C allows strings defined in the source via this style to be stored in a read-only data section. Check this output:
$ cat storage.c
int main(int argc, char* argv[]) {
char *arr[] = {"hello", "world"};
arr[1][1]='a';
return 0;
}
$ make storage
cc storage.c -o storage
$ readelf -p.rodata storage
String dump of section '.rodata':
[ 4] hello
[ a] world
My compiler has placed the strings into the .rodata
read-only data section. When I try to update the o
to an a
in the program, the program dies:
$ ./storage
Segmentation fault (core dumped)
This is general applies to any code that defines strings as the following:
char *foo = "string";
If you want to create a modifiable string in the program source, you'd write it instead like this:
char foo[] = "string";
I'm not entire sure what the syntax would be to create an array of modifiable strings; at least the following ugly approach works, but I'm sure there's something better:
char a1[] = "hello";
char a2[] = "world";
char *arr[] = {a1, a2};
Upvotes: 3
Reputation: 18532
The runtime crash is due to you modifying the string literals in arr
. The string literals "Brinda Roy"
, "Rakesh Bai"
, "Neha Saxen"
and "Ankit Jain"
should be treated as const char[]
, as they may be stored in a read-only section of your program. Attempting to change their values causes undefined behaviour, as mentioned in the comments below.
If you want to edit these read-only strings, you're going to need to make copies of them into non-const
buffers.
If you do:
char *str = "message"
you shouldn't modify the data pointed to by str
because it's pointing to read-only memory.
If you do:
char str[] = "message"
you can modify the data pointed to by str
because the read-only string literal "message"
is being copied into the array str
.
Your code falls into the first scenario above.
Upvotes: 5