编辑*:我知道有类似的问题,但是由于这是一个练习作业,因此给出了函数签名,并且只允许我更改函数体。因此,我无法更改函数参数或返回类型,例如类似线程上的答案。预先感谢!
我真的对正在编写的程序感到困惑。我基本上是在编写一个函数,该函数需要两个指向结构的指针,这些结构具有一个int组件和一个字符数组组件。该函数附加了两个字符数组组件以返回结构(类似于strcat)。问题是,虽然结构的数组部分由函数更新,但int部分却没有。谁能解释为什么?函数newText创建一个新的结构文本,并将该结构的数组设置为该函数的参数。它还将容量设置为24。如果string参数的长度大于24,则它将容量加倍,直到适合为止。 append函数附加两个字符串,然后使用新附加的字符串调用newText并将t1设置为等于newText的返回值。我在append函数的末尾有打印语句,以向我展示它的工作原理和值正确,但是在主函数中,我调用该函数后,t->容量再次变为24,而不是48,而t->内容正确。这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <assert.h>
struct text { int capacity; char *content; };
typedef struct text text;
text *newText(char *s) {
text *t = malloc(sizeof(text));
t->capacity = 24;
while (strlen(s) + 1 > t->capacity) {t->capacity = t->capacity * 2;}
t->content = malloc(t->capacity);
strcpy(t->content, s);
return t;
}
void append(text *t1, text *t2) {
int length1 = strlen(t1->content);
int length2 = strlen(t2->content);
int lengths = length1 + length2;
for (int i = length1; i < length1 + length2; i++){
t1->content[i] = t2->content[i - length1];
t1->content[i + 1] = '\0'; }
char text[100];
strcpy(text, t1->content);
t1 = newText(text);
printf("%s \n", t1->content);
printf("%d \n", t1->capacity);
}
int main () {
text *t = malloc(sizeof(text));
text *t1 = malloc(sizeof(text));
t = newText("carpet");
t1 = newText("789012345678901234");
append(t, t1);
printf("%d\n", t->capacity);
}
答案 0 :(得分:1)
t1 = newText(text);
在这里,您将t1
设置为新的text
。但是,text
指向的原始t1
在这里没有改变。它仍然指向同一地方。传递给函数的指针是原始指针的副本,因此即使t1
指向新的text
,原始指针也不会。
所以当您在这里打印时
printf("%d\n", t->capacity);
您仍然会获得旧的容量值。或更确切地说,是旧 t1
的容量。而这里
printf("%s \n", t1->content);
printf("%d \n", t1->capacity);
您正在打印新content
的{{1}}和capacity
,在函数结束后,指针将丢失到该指针。
例如,您可以通过返回该指针来解决此问题。将签名更改为
t1
在函数末尾:
text* append(text *t1, text *t2)
然后您更新return t1;
,所以更改此
t1
收件人
append(t, t1);
还要注意内存泄漏。现在,在t1 = append(t, t1);
中,您将指针指向两个有效的append
,并分配了一个新的text
,在函数结尾,您仍然只有两个指向text
的指针,而您没有text
。这表明我们一个人被泄漏了。
编辑:
如果您不能更改函数的签名,则不能返回新的free
或使用双指针将其传递出去。在这种情况下,我建议不要制作新的text
而是只更改text
。使用t1
可以更改缓冲区的大小(实际上,它可能只是分配一个新的缓冲区,复制数据并释放旧的缓冲区),以便可以附加realloc
的内容。 / p>
t2
答案 1 :(得分:0)
为了修改函数中的指针并将其传递回去,您必须传递该指针的地址,例如:
void test(char** ppTest) {
//Is anything valid passed?
if ( ppTest == NULL ) {
return;
}
*ppTest = "Hello World";
}
int main(void) {
char* pTest = NULL;
printf("Before function call pTest: %s\n", (pTest == NULL) ? "NULL" : pTest);
test(&pTest); // Must pass the address of the pointer
printf("After function call pTest: %s\n", (pTest == NULL) ? "NULL" : pTest);
return 0;
}