1

I am trying to add a string to an array, but I'm not sure how come this code isn't working. Would anyone please be able to leave me some feedback?

    /* Exercise b: Add <string> to the end of array <array>.
 * Returns: pointer to the array after the string has been added.
 */
char **add_string(char **array, const char *string) {
    /*reallocate so the array of strings can hold one more string*/
    char** newArray = realloc(array, sizeof (array) + sizeof (char*));
    if (!newArray) return array;

    /*allocate memory for new string*/
    char* newString = malloc(strlen(string) * sizeof (char));
    if (!newString) return newArray;

    /*copy old string to new string*/
    int lastIndex = sizeof (newArray) / sizeof (char*);
    strncpy(newString,string,strlen(string));

    /*null terminate array and set old end of array to new string*/
    newArray[lastIndex] = NULL;
    newArray[lastIndex-1] = newString;

    return newArray;
}

When I run the code, the core dumps, but I dont see why

The reason why I am asking is because I am aware that it would be easy to pass in the size of the array. But for this method, I am not allowed. Unfortunatley, my professor does says that the fuction parameters must stay the same

yasgur99
  • 756
  • 2
  • 11
  • 32
  • You could try debugging the code -- for example, start by printing out `sizeof(array)` and `lastIndex` and seeing if they're taking the values you expect. – Paul Hankin Dec 20 '16 at 22:33
  • 3
    `sizeof (newArray)` that does not do what you want. `sizeof` on a pointer gives the pointer size not the array size (because it is not actually a C array - pointers and arrays are different in C even though they behave similar in many cases). – kaylum Dec 20 '16 at 22:33
  • Possible duplicate of [How to find the 'sizeof'(a pointer pointing to an array)?](http://stackoverflow.com/questions/492384/how-to-find-the-sizeofa-pointer-pointing-to-an-array) – kaylum Dec 20 '16 at 22:35
  • @kaylum the exercise is to do this without passing in another parameter. all i know is that the last element in the array is NULL. So the methods listed in that article do not apply – yasgur99 Dec 20 '16 at 22:39
  • 1
    If all you know is that the last element in the array is `NULL`, you have to loop through the array until you find `NULL`, and count the elements. Then you can add 1 to that and multiply by `sizeof(char*)` – Barmar Dec 20 '16 at 22:42
  • 2
    `malloc(strlen(string))` is pretty much always wrong. – melpomene Dec 20 '16 at 22:45
  • @melpomene not once does it say that in my code? – yasgur99 Dec 20 '16 at 22:49
  • @yasgur99 Not literally (you have a redundant multiplication by `1` in there), but it does the same thing. – melpomene Dec 20 '16 at 22:50
  • @melpomene well if i want to add 5 characters, and each character is one byte, then i need 5 bytes. what is wrong wit that? – yasgur99 Dec 20 '16 at 22:52
  • @yasgur99 C strings also have a NUL terminator at the end. – melpomene Dec 20 '16 at 22:53
  • @yasgur99 According to the comment before the function you should not create any new array. You have to add a string to the current character array and return pointer to its first element. – Vlad from Moscow Dec 20 '16 at 22:54
  • @yasgur99-- note that `strlen()` does not count the `NUL` terminator. – ad absurdum Dec 20 '16 at 22:59

1 Answers1

1

There are several things wrong, e.g. sizeof (array) + sizeof (char*), where sizeof(array) is wrong and the + as well (should be *); and all the other comments above also apply.

Wrote a solution and left your code as comments; see the differences.

/* Exercise b: Add <string> to the end of array <array>.
 * Returns: pointer to the array after the string has been added.
 */
char **add_string(char **array, const char *string) {

    int lastIndex = 0;
    while (array[lastIndex] != nullptr)
        lastIndex++;

    /*reallocate so the array of strings can hold one more string; note that lastIndex is zero-based; hence, the size of the current array is lastIndex+1, and consequently the size of the new array needs to be lastIndex+2 */
    // char** newArray = (char**)realloc(array, sizeof (array) + sizeof (char*));
    char** newArray = (char**)realloc(array, (lastIndex+2) * sizeof (char*));
    if (!newArray) return array;

    /*allocate memory for new string*/
    char* newString = strdup(string);
    //char* newString = malloc(strlen(string) * sizeof (char));
    if (!newString) return newArray;

    /*copy old string to new string*/
    //int lastIndex = sizeof (newArray) / sizeof (char*);
    //strncpy(newString,string,strlen(string));


    /*null terminate array and set old end of array to new string*/
    //newArray[lastIndex] = NULL;
    //newArray[lastIndex-1] = newString;

    newArray[lastIndex++] = newString;
    newArray[lastIndex] = nullptr;

    return newArray;
}

void printArray (char** array) {
    char* str; int i=0;
    while ((str = array[i]) != nullptr) {
        std::cout << i << ":" << str << std::endl;
        i++;
    }
}

int main() {

    char** myArray = (char**) malloc(1 * sizeof(char*));
    myArray[0] = nullptr;

    std::cout << "empty:" << std::endl;
    printArray (myArray);

    myArray = add_string(myArray, "Tom");
    std::cout << "one element:" << std::endl;
    printArray (myArray);

    myArray = add_string(myArray, "Jerry");
    myArray = add_string(myArray, "Fin");
    std::cout << "three elements:" << std::endl;
    printArray (myArray);

    return 0;
}
Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58