views:

1605

answers:

2

I am using this example:

char *myData[][2] =
{{"John", "[email protected]"},
 {"Erik", "[email protected]"},
 {"Peter","[email protected]"},
 {"Rikard","[email protected]"},
 {"Anders","[email protected]"}};   

char **tableData[6];
tableData[0] = myData[0];
tableData[1] = myData[1];
tableData[2] = myData[2];
tableData[3] = myData[3];
tableData[4] = myData[4];
tableData[5] = NULL;//null terminated array

and instead want to place my own strings for name and emails. (trying to place string xyz into myData, then tableData) strcpy with myData wont work. I have tried all combination's of pointers and referencing but it doesn't seem to copy the string. Any suggestions?

          ok--> strncpy(xyz, argv[i], strlen(argv[i]));
          ok--> strcpy(xyz + strlen(argv[i]), "\0");
run time stops here--> strncpy(myData[i][0], xyz, strlen(xyz));  
                tableData[i] = myData[i];
+3  A: 

The pointers in myData[][] as you have it initialized point to literal strings. That memory cannot be written to.

You can allocate new memory for your new strings and place the pointers to the new strings into myData. Or for what you seem to be doing, just store the pointers to the argv[] strings (as long as you're not planning to modify the strings later).

Also, please make sure that the memory block you're copying strings into is large enough to hold the new string.

Software Monkey Edit: Including the \0 terminator; and make sure you free the memory when appropriate.

Michael Burr
A: 

Create you own local copy of the data and change the pointer in the list:

char **newentry = malloc(sizeof(char*) * 2);
newentry[0] = strdup(myNewName);
newentry[1] = strdup(myNewEmail);
tableData[i] = newentry;

That's the easy part. The hard part is freeing the memory when you are finished. If this is just a little throwaway C program, you can probably get away without freeing memory since the operating system will automatically free it when the app exits.

But if you want to do it Properly with a capital 'P', I'd make a couple of little functions to copy and free table items:

void tableFreeItem(int i)
{
    if(tableData[i] != 0)
    {
       free(tableData[i][0]);
       free(tableData[i][1]);
       free(tableData[i]);
    }
}

void tableSetItem(int i, char *name, char *email)
{
    tableFreeItem(i);

    tableData[i] = malloc(sizeof(char *) * 2);
    tableData[i][0] = strdup(name);
    tableData[i][1] = strdup(email);
}

Now we can replace items in the list at will and we can easily free the memory by calling the tableFreeItem() function. Here is an example of how you can use these functions:

#define TABLE_SIZE 5

char **tableData[TABLE_SIZE + 1]; /* +1 to make room for NULL terminator */

/* Clear out the table. This also sets up the NULL terminator at the end. */
    memset(tableData, 0, sizeof(tableData));

/* Copy the original data into the table */
    for(i = 0; i < TABLE_SIZE; i++)
     tableSetItem(i, mydata[i][0], myData[i][1]);

/* Change a data item */
    tableSetItem(3, "Adam Pierce", "[email protected]");

/* Free memory when we have finished */
    for(i = 0; i < TABLE_SIZE; i++)
     tableFreeItem(i);

DISCLAIMER: I have not tried to compile or run this code, I just banged it off from the top of my head. It will probably work.

Adam Pierce