从现有字符串中动态构造一个数组,而无需新的malloc

时间:2018-11-21 19:41:49

标签: c pointers segmentation-fault malloc

我想动态分配一个字符串数组。 因此, arr 应该由指向每个字符串第一个字符的二十个指针组成。

为简单起见,每个字符串都是相同的,存储在 base 中。 现在,第一个for循环应该可以创建我的数组,它看起来可以正常工作。

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

int main()
{
  int n = 20;
  char** arr = malloc( sizeof(char*) + n );

  char* base = "abcdefghijklmnopqrstuvwxyz";

  for(int i = 0; i < n; i++)
  {
    *(arr + sizeof(char*) * i) = base;
  }

  for(int i = 0; i < n; i++)
  {
    printf("%s\n", *(arr + sizeof(char*) * i));
  }
}

循环秒数在第二次迭代期间会创建分段故障

1 个答案:

答案 0 :(得分:5)

问题

  1. char** arr = malloc( sizeof(char*) + n );分配(最可能)24个字节,该字节最多只能存储(最可能)六个char *

  2. 您无需尝试通过基本类型偏移地址(*(arr + sizeof(char*) * i) = base;)。偏移量由sizeof基本类型自动调整。

必须进行以下更改:

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

int main(void)
{
    int n = 20;
    char **arr = malloc(sizeof(char *) * n);

    char *base = "abcdefghijklmnopqrstuvwxyz";

    for(int i = 0; i < n; i++)
        arr[i] = base;

    for(int i = 0; i < n; i++)
        printf("%d: %s\n", i, arr[i]);

    return 0;
}

前面使用数组表示法。您也可以根据需要使用指针符号。将arr[i]更改为*(arr + i)

输出

$ gcc main.c -o main.exe; ./main.exe
0: abcdefghijklmnopqrstuvwxyz
1: abcdefghijklmnopqrstuvwxyz
2: abcdefghijklmnopqrstuvwxyz
3: abcdefghijklmnopqrstuvwxyz
4: abcdefghijklmnopqrstuvwxyz
5: abcdefghijklmnopqrstuvwxyz
6: abcdefghijklmnopqrstuvwxyz
7: abcdefghijklmnopqrstuvwxyz
8: abcdefghijklmnopqrstuvwxyz
9: abcdefghijklmnopqrstuvwxyz
10: abcdefghijklmnopqrstuvwxyz
11: abcdefghijklmnopqrstuvwxyz
12: abcdefghijklmnopqrstuvwxyz
13: abcdefghijklmnopqrstuvwxyz
14: abcdefghijklmnopqrstuvwxyz
15: abcdefghijklmnopqrstuvwxyz
16: abcdefghijklmnopqrstuvwxyz
17: abcdefghijklmnopqrstuvwxyz
18: abcdefghijklmnopqrstuvwxyz
19: abcdefghijklmnopqrstuvwxyz

根据Swordfish的建议,您应在constarr上使用base限定词:

const char **arr = malloc(sizeof(char *) * n);
const char * const base = "abcdefghijklmnopqrstuvwxyz";

通过这种方式:

  1. arr不能更改(没有警告/错误)指向char的指针。
  2. base的地址或指向char的指针都不能更改(没有警告/错误)。

谢谢

Tim Randall遇到数学错误。