0

I have tried everything and my code looks perfectly fine to me (it obviously isn't if it's not working).

I am trying to read from some text a list of words separated by a comma, and each word will be an element of an array of strings. I don't know how many elements there will be or how long it will be.

The for loop is grand, as I count how many characters there is before. The main problem is allocation memory, sometimes I get "Segmentation Fault: 11" when I run it (as it compiles grand), sometimes when I read the items it get something like:

P?? adios (null) heyya

When it should give me something like:

hola adios bye heyya

I think I am accessing memory I am not supposed to. Anyway, here the code:

// We allocate memory for one string
variables = (char**)calloc(1, sizeof(char*));
variables[0] = (char*)calloc(100, sizeof(char));

if (variables == NULL) {
    return NULL;
}

// Now we start looking for the variables
for (int i = comma_pos+1; i < *(second_pos + pos); i++) {
    deleteSpaces(string, &i);
    // If the character is not a comma, we copy the character
    if (*(string + i) != ',') {
        *(variables[stringnum] + j) = *(string + i);
        j++;
    } else {
        // If the character is a comma, we have to allocate more memory for a new string
        *(variables[stringnum] + j) = '\0';
        stringnum++;
        j = 0;

        char **temp = variables;
        // We allocate more memory for a second array
        variables = realloc(variables, sizeof(char*) * stringnum);

        variables[stringnum] = (char*)calloc(100, sizeof(char));


        // If we cannot allocate more memory then get out
        if (variables == NULL) {
            return temp;
        }
    } // end else
} // end for

*(variables[stringnum] + j) = '\0';
4
  • 1
    The definitions of your variables are not trifling details to be omitted for brevity, they are very important. Show them. Commented May 6, 2017 at 19:09
  • I know it can be done, need to allocate an array of pointers however deep, and then for each pointer in that array you need to do another alloc for however wide that one row is, repeat for each row, so if you have 8 deep you are doing 9 allocs... no matter how wide. Commented May 6, 2017 at 19:25
  • It is far easier to treat it as a one dimensional array/pointer allocate the space for all the strings, and then link list or hop your way through them in some way. Commented May 6, 2017 at 19:26
  • before you try to use one of your strings (string pointers) if you are going to do the bunch of allocs approach, go through and print the addresses of all the stuff you allocated, see if it makes any sense. (not while doing it!) in a separate loop after, walk through each one... Commented May 6, 2017 at 19:28

2 Answers 2

1

It's not immediately clear to me what is wrong with your code, but it's not at all how I would approach the problem.

I would start by determining how many substrings there are by counting delimiters in the source string and adding one. This does require a pre-scan of the string, but it's likely to be much cheaper than any alternative that requires performing multiple memory allocations.

As for space for the strings themselves, if you do not need to keep the comma-delimited form of the list, then you may be able to re-use that space. Use the strtok() function to tokenize it, and store the resulting pointers.

If you must preserve the original comma-delimited string, then I suggest making a copy of the whole thing, and then tokenizing as I suggested before (and you will know how long it is already from counting delimiters). You do not need more space overall for the individual strings than the original comma-delimited one occupies.

If you prefer to avoid strtok() then it's not hard to implement the same thing manually.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much, i did not use strok() but the thing about counting elements makes everything much much easier, it makes sense, thank you :)
0

you have to alloc in both directions and maybe you are already.

you need to allocate the depth, an array of pointers, then for each pointer in that array need to allocate the width for that row.

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

int main ( void )
{
    unsigned int ra;
    unsigned int rb;

    char **x;

    x=malloc(100*sizeof(char *));
    printf("%p\n",x);
    for(ra=0;ra<100;ra++)
    {
        x[ra]=malloc(ra*sizeof(char));
    }

    for(ra=0;ra<100;ra++)
    {
        printf("%p\n",x[ra]);
    }

    for(ra=0;ra<100;ra++)
    {
        for(rb=0;rb<ra;rb++) x[ra][rb]=rb;
    }
    for(ra=0;ra<100;ra++)
    {
        for(rb=0;rb<ra;rb++)
        {
            printf("%u ",x[ra][rb]);
        }
        printf("\n");
    }

    return(0);
}

Comments

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.