如何 "rebuild" 一个腐烂的 **char?
How to "rebuild" a decayed **char?
以下代码是我的大型程序的简化版本,用于演示该问题。
#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
?
您可以简单地将其分配给 f()
中的正确类型:
char **f_words = v;
for (int i=0; i<m; i++) {
printf("%s\n", f_words[i]);
}
此外,您在 f()
中识别单词长度的方法并不好。
您可以将长度作为附加参数传递给 f()
,或者您可以使用 NULL
指针终止单词列表。
考虑将 struct
传给 f()
。这将使获取 len
、m
和 words
更加清晰,并且没有全局变量。
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});
...
}
以下代码是我的大型程序的简化版本,用于演示该问题。
#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
?
您可以简单地将其分配给 f()
中的正确类型:
char **f_words = v;
for (int i=0; i<m; i++) {
printf("%s\n", f_words[i]);
}
此外,您在 f()
中识别单词长度的方法并不好。
您可以将长度作为附加参数传递给 f()
,或者您可以使用 NULL
指针终止单词列表。
考虑将 struct
传给 f()
。这将使获取 len
、m
和 words
更加清晰,并且没有全局变量。
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});
...
}