【问题标题】:How to "rebuild" a decayed **char?如何“重建”腐烂的**char?
【发布时间】:2021-03-18 21:43:37
【问题描述】:

以下代码是我的较大程序的简化版本,用于演示问题。

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

const int m = 5;
char **words1;
char **words2;

void f(void *v) {
    printf("v: %p\n", v);

    int len = v==words1 ? 3 : 4;
    printf("len: %d\n", len);

    for (int i=0; i<m; i++) {
        // What goes here?
        /*
        char *c = malloc(sizeof(char) * len);
        c = (char*)v; // Something _like_ this?!
        printf("%s\n", c);
        */
    }
}

int main(int argc, char *argv[]) {

    words1 = malloc(m * sizeof(char*));
    printf("%p\n", words1);
    words2 = malloc(m * sizeof(char*));
    printf("%p\n", words2);

    for (int i=0; i<m; i++) {
        words1[i] = malloc(sizeof(char) * 3);
        words2[i] = malloc(sizeof(char) * 4);
        strcpy(words1[i], "22");
        strcpy(words2[i], "333");
    }

    f(words1);
    f(words2);

    for (int i=0; i<m; i++) {
        free(words1[i]);
        free(words2[i]);
    }
    free(words1);
    free(words2);
}

我有两个全局 **char认为在堆上(因为 malloc)。

f()的签名不能改变,即只能接受void *

重要的是,在实际程序中,**char 中的数据对于堆栈来说太大了。

简而言之:如何从*void 取回**char

【问题讨论】:

  • 首先,为什么这些变量是全局变量?但专门针对您的问题,您可以分配它:char **s = v;
  • c = malloc(sizeof(char) * len); c = (char*)v; 请注意,这没有意义,因此不清楚作为您想要做什么的示例。因为malloc 某事然后立即在下一行覆盖/丢弃它是没有意义的。

标签: c void-pointers


【解决方案1】:

您可以在f() 中简单地将其分配给正确的类型:

   char **f_words = v;
    for (int i=0; i<m; i++) {
        printf("%s\n", f_words[i]);
    }

另外,您识别f() 中单词长度的方法也不好。

您可以将长度作为附加参数传递给f(),也可以使用NULL 指针终止单词列表。

【讨论】:

  • 谢谢!我也见过char **f_words = (char **)v; - 是一样的,只是对读者“更好”吗?
  • @Bridgey 空指针 (void*) 与任何其他数据指针的赋值兼容。所以演员阵容是不必要的。
【解决方案2】:

考虑将struct 传递给f()。它将使获取lenmwords 更加简洁,并且没有全局变量。

struct S {
  int len;
  int m;
  char **words;
};

void f(void *v) {
  struct S *s = v;
  int len = s->len;
  int m = s->m;
  char **word = s->words;
  
  printf("v: %p\n", v);
  printf("len: %d\n", len);
  for (int i = 0; i < m; i++) {
       printf("%s\n", words[i]);
}


int main(int argc, char *argv[]) {
   ...
   // passing a pointer to compound literal
   f(&(struct S){ 3, m, words1});
   f(&(struct S){ 4, m, words2});
   ...
}

【讨论】:

  • 谢谢!我接受了 P.P 的回答,因为它是针对我的具体问题的第一个也是最直接的问题,但您的回答绝对是我将来会实施的。谢谢!
猜你喜欢
  • 1970-01-01
  • 2015-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-01
  • 2022-08-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多