C 中的内存访问冲突:尝试将子字符串从 char** 写入 char**

Memory access violation in C : Trying to write substrings from char** to char**

我有一些字符串存储在这样的二维字符数组中:

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";

现在我想从每个字符串中取出一个特定的子字符串并将它们存储在另一个二维字符数组中。假设我想要这个的每个子字符串,直到看到 ':' 字符。如何在不导致内存访问冲突的情况下完成此操作?我试过这样但我发现违规了:(

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);

你必须分配缓冲区来存储东西并将它们分配给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);

如果你想复制字符串文字的子字符串,你需要分配一个内存来复制子字符串。

这是一个演示程序,展示了它是如何完成的。

#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;
}

程序输出为

this
another
hello
thank