2

I am trying to swap 2 elements in an array of pointers, and these pointers point to strings of different length. Another function handled allocating memory to the array and the strings, the swap function will simple take an char** array and swap the elements I need to swap. What I am wondering is when I swap the pointers, is the allocated memory for each string retained when I swap or does this get messed up?

This isn't my exact code from my project, but what it's doing is identical:

int main() {

    char** array = malloc(10 * sizeof(char*));
    char* a = (char*)malloc(4*sizeof(char*));
    char* b = (char*)malloc(14*sizeof(char*));

    a = "test";
    b = "this is a test";

    array[0] = a;
    array[1] = b;

    char*temp;
    temp = array[0];
    array[0] = array[1];
    array[1] = temp;


    free[array];
    free[a];
    free[b];

    return 0;

}

Too summarize, my question is in regard to the allocated memory of a and b. Is that allocated memory still correct/fine after the swap?

0

1 Answer 1

4

The swap is fine. The problem is how you are allocing memory for the a and b pointers and how you are assigning strings to them. And no, when you use the swap algorithm the blocks of memory won't be scrambled. If you do not change a and b, then you will be fine (which you are doing). In C, things work like this:

char *a = malloc(4 * sizeof(char));
a = "test"; // this is an error, and you will lose the memory block

This is allocating 4 units of memory, each unit is of the size of a char. When you do:

char *a = malloc(4 * sizeof(char**));

This is allocating 4 units of memory, each unit is of the size of char *, or a pointer to char. This is not what you intended. Furthermore, if you want to put a string in a pointer to char, you should use the strncpy function (or strndup if available).

char *a = malloc(5 * sizeof(char)); // always alloc space for the NULL byte
strncpy(a, "test", 4);

char *b = strndup("test", 4); 

free(a);
free(b);

Note that you did alloc the memory for the array of pointers in the right way, doing:

char **array = malloc(10 * sizeof(char*));

... will give you a block of 10 units of memory, each of which are of the size of char *. Then you can address each of those units of memory by indexing the array pointer.

Couple pointers (no pun): first, you don't need to cast the return of malloc. Second, you don't need to multiply by sizeof(char). Bellow is a little working version of the code.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    char **array = malloc(10 * sizeof(char*));
    char *a = malloc(5);
    char *b = malloc(15);

    strcpy(a, "test");
    strcpy(b, "this is a test");

    char *temp;

    array[0] = a;
    array[1] = b;

    // prints "test" then "this is a test"
    printf("%s\n%s\n\n", array[0], array[1]);

    // this swaps them
    temp = array[0];
    array[0] = array[1];
    array[1] = temp;

    // now it prints "this is a test" and "test"
    printf("%s\n%s\n\n", array[0], array[1]);

    free(a);
    free(b);
    free(array);
}
Sign up to request clarification or add additional context in comments.

2 Comments

Ahh okay I see. The problem is that in another function, I am given a string and I have to take substrings from it. For this reason I am using memcpy. I first declare something like char* a = malloc(N * sizeof(char*)), then memcpy(a, originalString, n) where n is however many bytes I'm taking from the original string. If I change it to look like yours, char*a = malloc(stringlength), memcpy(a, originalString, n), then add to the array array[0] = a, would that be fine?
@JackKelly Yes, it would be fine as you described. Strings are held by pointers to char, and each character only takes up a byte, so you only need the malloc(n) call. memcpy(a, originalString, n) will copy n bytes from originalString into the a string. Note that if the space in a is less then n, then you will have memory overflow (undefined behavior follows).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.