2

I have some strings stored inside a 2D character array like that:

char** strings = malloc(4*sizeof(char*));
strings[0] = "this:is,an,example\n";
strings[1] = "another:example\n";
strings[2] = "hello:dear,world\n";
strings[3] = "thank:you,for,help\n";

Now I'd like to take a specific substring from each of these strings and store them inside another 2D character array. Let's say I want every substring of this until seeing a ':' character. How can this be done without causing memory access violation? I have tried it like this but I get the violation :(

char** substrings = malloc(4*sizeof(char*));
for(int i=0; i<4; i++) {
   for(int j=0; strings[i][j] != ':'; j++) {
      substrings[i][j] = strings[i][j];
   }
}

free(strings);
free(substrings);
GMachado
  • 791
  • 10
  • 24
ilse_al
  • 23
  • 4

2 Answers2

1

You must allocate buffer to store things and assign them to the elements of substrings.

char** substrings = malloc(4*sizeof(char*));
for(int i=0; i<4; i++) {
   substrings[i] = calloc(strlen(strings[i]), sizeof(char)); /* allocate buffer */
   for(int j=0; strings[i][j] != ':'; j++) {
      substrings[i][j] = strings[i][j];
   }
}

free(strings);
/* free buffer */
for(int i=0; i<4; i++) {
   free(substrings[i]);
}
free(substrings);
MikeCAT
  • 73,922
  • 11
  • 45
  • 70
1

If you want to copy a substring of a string literal you need to allocate a memory where the substring will be copied.

Here is a demonstrative program that shows how it can be done.

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

int main(void) 
{
    enum { N = 4 };
    char** strings = malloc( N * sizeof( char* ) );
    
    size_t i = 0;
    
    strings[i++] = "this:is,an,example\n";
    strings[i++] = "another:example\n";
    strings[i++] = "hello:dear,world\n";
    strings[i++] = "thank:you,for,help\n";
    
    char** substrings = malloc( N * sizeof( char* ) );
    
    for ( i = 0; i < N; i++ )
    {
        char *p = strchr( strings[i], ':' );

        substrings[i] = calloc( 1, 1 + ( p == NULL ? strlen( strings[i] ) 
                                                   : p - strings[i]  ) );
                                                   
        if ( p == NULL )
        {
            strcpy( substrings[i], strings[i] );
        }
        else
        {
            memcpy( substrings[i], strings[i], p - strings[i] );
        }
    }
    
    for ( i = 0; i < N; i++ )
    {
        puts( substrings[i] );
    }

    for ( i = 0; i < N; i++ )
    {
        free( substrings[i] );
    }
    free( substrings );
    
    free( strings );
    
    return 0;
}

The program output is

this
another
hello
thank
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335