views:

85

answers:

4

I am currently trying to allocate the same amount of memory for a double pointer. I take in a char** and want to use a bubble sort on that char** . So I create a temp char** and now I'm wondering how to correctly allocate enough memory so that I can return that temp char** to another method.

I know the way I'm allocating right now doesn't look right and it certainly doesn't work...otherwise I wouldn't be asking this question. If someone could respond with some helpful advice, I would greatly appreciate it!

char** bubble_sort(char **filenames, int n)
{
    int i;
    char **new_list;
    new_list = malloc(sizeof(filenames));
    for (i = 0; i < n; i++)
    {
       // malloc(file_list.size * sizeof(int));
        new_list[i] = filenames[i];
    }
    for (i = 0; i < n; i++)
    {
        printf("%d: %s\n", i, new_list[i]);
    }

    int x;
    int y;
    for(x=0; x<n; x++)
    {
            for(y=0; y<n-1; y++)
            {
                    if(new_list[y]>new_list[y+1])
                    {
                            char *temp = new_list[y+1];
                            new_list[y+1] = new_list[y];
                            new_list[y] = temp;
                    }
            }
    }
    for (i = 0; i < n; i++)
       {
           printf("%d: %s\n", i, new_list[i]);
       }
    return new_list;
}
+1  A: 

filenames is a pointer to pointer to char, therefore on this line...

new_list = malloc(sizeof(filenames));

...you're allocating the amount of the size of the pointer (to pointer), which isn't what you want.

You probably want malloc(sizeof(filenames) * n); which will give you the space for n pointers.

Luca Matteis
that's giving me "invalid operands to binary * (have 'char**' and 'int)
Brandon
Sorry, i had a typo.
Luca Matteis
+2  A: 
char** bubble_sort(char **filenames, int n) 
{ 
    int i; 
    char **new_list; 
    new_list = malloc(sizeof(filenames)); 

This code allocates enough space to store a single pointer (sizeof(filenames) is mostly likely 4), and gives the address of that pointer to new_list. If you want to access what new_list points to as an array (and I know you do, because you tried to do just that below), you'll need to allocate enough space for its elements.

T.E.D.
A: 

This is somewhat of a duplicate. See: http://stackoverflow.com/questions/3150268/creating-char-data/3150445

There are serious memory performance issues with respect to allocating at char** for a 2D array. Better to use a char* and a indexing scheme. In this way you get a contiguous chunk of memory. You can also use a one-D std::vector with such a scheme.

If you must allocate a char**, the for loop is all you can do AFAIK. But at least make a subroutine out of that! :)

Craig W. Wright
A: 

Here is the working copy of the program:

#include <cstdio>
#include <cstdlib>
#include <cstring>

char** bubble_sort(const char **filenames, int n)
{
    int i;
    char **new_list;
    new_list = (char**) malloc(sizeof(*new_list) * n);
    for (i = 0; i < n; i++)
    {
        new_list[i] = (char*) filenames[i];
    }

    printf("Initial list:\n");
    for (i = 0; i < n; i++)
    {
        printf("%d: %s\n", i, new_list[i]);
    }

    int x;
    int y;

    printf("List is sorted:\n");
    for(x=0; x<n; x++)
    {
            for(y=0; y<n-1; y++)
            {
                    if(strcmp(new_list[y],new_list[y+1])>0)
                    {
                            char *temp = new_list[y+1];
                            new_list[y+1] = new_list[y];
                            new_list[y] = temp;
                    }
            }
    }
    for (i = 0; i < n; i++)
       {
           printf("%d: %s\n", i, new_list[i]);
       }
    return new_list;
}

int main(){
    const char *ar[5]={
        "eee", "aaa", "bbb", "ccc", "ddd",
    };
    bubble_sort(ar, 5);
    return (0);
}

Still, keep in mind that your programming style resembles more to C than C++ (which is not always a bad thing).

If you want to allocate new strings for your array elements, you should change the first for like this:

for (i = 0; i < n; i++)
{
    //new_list[i] = (char*) filenames[i];
    new_list[i] = (char*) malloc(sizeof(**new_list) * (strlen(filenames[i]) + 1));
    strcpy(new_list[i], filenames[i]);
}

And this is the C version (first one was the C++ version). Note that the string array has all its elements newly allocated, and is not using the initial strings from the input parameter.:

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

char** bubble_sort(char **filenames, int n)
{
    int i;
    char **new_list;
    new_list = malloc(sizeof(*new_list) * n);
    for (i = 0; i < n; i++)
    {
        //new_list[i] = (char*) filenames[i];
        new_list[i] = malloc(sizeof(**new_list) * (strlen(filenames[i]) + 1));
        strcpy(new_list[i], filenames[i]);
    }

    printf("Initial list:\n");
    for (i = 0; i < n; i++)
    {
        printf("%d: %s\n", i, new_list[i]);
    }

    int x;
    int y;

    printf("List is sorted:\n");
    for(x=0; x<n; x++)
    {
            for(y=0; y<n-1; y++)
            {
                    if(strcmp(new_list[y],new_list[y+1])>0)
                    {
                            char *temp = new_list[y+1];
                            new_list[y+1] = new_list[y];
                            new_list[y] = temp;
                    }
            }
    }
    for (i = 0; i < n; i++)
       {
           printf("%d: %s\n", i, new_list[i]);
       }
    return new_list;
}

int main(){
    char *ar[5]={
        "eee", "aaa", "bbb", "ccc", "ddd",
    };
    bubble_sort(ar, 5);
    return (0);
}
Andrei Ciobanu
oops...yep, I'm programming everything else in C++, but forgot that this was in C. I'll try your solution out in just a second.
Brandon
@Brandon This part is in C?! If this is so, please change the tag, and I'm going to delete all my comments then since they don't apply. The C experts should speak.
Daniel Daranas
Note that in the C version you should change the header files, and there's no need for type casting after malloc . Oh, and another thing, take care when you compare C strings. Do that using strcmp function from string.h (or cstring if C++).
Andrei Ciobanu
I would not describe any of that code as C++. It is all C with a smattering of namespace in the first).
Martin York
@Martin York, you are right. But i have only done some small edits on the initial code.
Andrei Ciobanu