built1n
built1n

Reputation: 1546

Changing one character in a char* array without converting to char[][]

I have a one-dimensional array of string literals of different lengths like so:

char *map[] = {
"ABC",
"ABCDEF",
...
};

I would like to change a certain character in the array with map[y][x]='X';, which does not (and should not) work according to Wikipedia. I also read that declaring it as char map[][] would fix the bug. However, this is a VERY large array so converting it to char map[][] will be impractical. Is there another way to accomplish what I want?

Upvotes: 2

Views: 268

Answers (5)

hdante
hdante

Reputation: 8030

#include <stdio.h>

char s1[] = "abcd";
char s2[] = "efghi";
char s3[] = "jklmnop";

char *s[] = {
  s1, s2, s3
};

int main(void)
{
  s[0][0] = '$';
  printf("%s %s %s\n", s[0], s[1], s[2]);
  return 0;
}

Edit: the above code replaces the pointer to strings by pointer to (writable) arrays of characters, resulting in the desired writable behavior.

Upvotes: 0

barak manos
barak manos

Reputation: 30136

This is an array of pointers to strings which are located in a read-only memory section:

char* map[] =
{
    "ABC",
    "DEF",
    ...
};

You can change the value of each pointer, but you cannot change the contents of the pointed memory.


This is an array of pointers to strings which are located in a read/write memory section:

char map[][MAX_STR_LEN+1] =
{
    "ABC",
    "DEF",
    ...
};

You cannot change the value of each pointer, but you can change the contents of the pointed memory.


Please note that in the second scheme, you have basically two options:

  1. Declare the array as a global variable, in which case it will reside in the data-section of the executable image and loaded into memory along with it (i.e., no initialization code executed).

  2. Declare the array as a local variable, in which case the function will include an additional piece of code for initializing the array every time it is called (copying all the strings from the RO-data-section into the stack).

Upvotes: 0

BLUEPIXY
BLUEPIXY

Reputation: 40145

#include <stdio.h> 

#define CNV(x) (char []){ x }

int main(void){
    char *map[] = {
    CNV("ABC"),
    CNV("ABCDEF"),
    //...
    };
    map[1][2]='c';
    printf("%s\n", map[1]);//ABcDEF
    return 0; 
} 

Upvotes: 2

sherrellbc
sherrellbc

Reputation: 4853

If you want to be able to change the strings contained in your array you are going to have to work with dynamically allocated memory. I would allocate an array of char* and then run through and allocate memory for each followed by a call to strncpy, or similar.

char** ptrArray = malloc(sizeof(char*)*NUM_STRINGS); 
...
ptrArray[0] = malloc(sizeof(someString)*sizeof(char));
strncpy(ptrArray[0], someString, sizeof(someString)); 

It really depends on the context of your application.

Upvotes: 1

Vlad from Moscow
Vlad from Moscow

Reputation: 311058

You may not change string literals. They are immutable in C/C++.

The more correct your definition of the array would look as

const char *map[] = {
"ABC",
"DEF",
...
};

You have to use a two-dimensional character array that to be able to change its elements.

For example

char map[][4] = {
    "ABC",
    "DEF",
    ...
    };

Or you could use the array of pointers changing the required element by assigning a new string literal to it.

Upvotes: 2

Related Questions