函数调用后结构指针的值不变

时间:2018-11-07 15:34:27

标签: c pointers struct

编辑*:我知道有类似的问题,但是由于这是一个练习作业,因此给出了函数签名,并且只允许我更改函数体。因此,我无法更改函数参数或返回类型,例如类似线程上的答案。预先感谢!

我真的对正在编写的程序感到困惑。我基本上是在编写一个函数,该函数需要两个指向结构的指针,这些结构具有一个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);
}

2 个答案:

答案 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;
    }