Swa
Swa

Reputation: 31

using Array of pointers

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

Answers (4)

jpalecek
jpalecek

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

Evans
Evans

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

sarnold
sarnold

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

AusCBloke
AusCBloke

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

Related Questions