简体   繁体   English

如何使结构内的指针指向另一个指针指向的同一个字符串?

[英]How do I make a pointer inside a struct point to the same string pointed by another pointer?

I have the following code:我有以下代码:

struct el{      
    char *line;
    struct el *next;
};
struct el *abc, def;
char *p1;
char buffer[100];
abc = &def;
gets(buffer);
p1 = malloc(strlen(buffer) + 1 );
strcpy( p1, buffer);

How can I make line point to the same string pointed by p1 without allocating the same string twice?如何在不分配相同字符串两次的情况下使line指向p1指向的同一个字符串? Is it enough to write:写一下就够了:

 abc->line = p1;

Or do I also need to free the area pointed by p1 ?还是我还需要释放p1指向的区域?

I sense something smelly... Namely, that all your variables seem to be local variables (on the stack) that cease to exist when your function returns.我感觉有些东西很臭......也就是说,你的所有变量似乎都是局部变量(在堆栈上),当你的函数返回时它们就不复存在了。

So would your function end with那么你的函数会以

return abc;

then you loose everything because you said abc= &def;然后你失去了一切,因为你说abc= &def; and def is also a local variable.def也是一个局部变量。 So yes, you can simply do abc->line= p1;所以是的,你可以简单地做abc->line= p1; but after the return you have lost abc (which points to def which was a stack variable that then no longer exists) and hence you have also lost abc->line and so you have a memory leak.但是在返回之后你丢失了abc (它指向def ,它是一个堆栈变量,然后不再存在),因此你也丢失了abc->line ,所以你有内存泄漏。

So you should expand the code you show us for us to be able to say "Yes you can do that".因此,您应该扩展您向我们展示的代码,以便我们能够说“是的,您可以做到”。

The following is an example of a function that is wrong:下面是一个错误函数的例子:

struct el{
    char *line;
    struct el *next;
};

struct el *example(void)
{
    struct el *abc, def;    // def is a local variable
    char *p1;
    char buffer[100];
        
    abc = &def;
    gets(buffer);
    p1 = malloc( strlen(buffer) + 1 );
    strcpy( p1, buffer);
    
    abc->line= p1;
    return abc;             // def won't exist anymore after the function returns
}

To fix this error, you should also do abc= malloc(sizeof(struct el));要修复此错误,您还应该执行abc= malloc(sizeof(struct el)); or pass a pointer variable to the function, for example:或将指针变量传递给函数,例如:

void example2(struct el *abc)
{
    char *p1;
    // ...
    abc->line= p1;
 }

and call as for example:并调用例如:

int main(void)
{
    struct el pqr = {0};
    example2(&pqr);
    // ...
}

How can I make line point to the same string pointed by p1 without allocating the same string twice?如何在不分配相同字符串两次的情况下使line指向p1指向的同一个字符串? Is it enough to write:写一下就够了:

 abc->line = p1;

Yes, you can do that.是的,你可以这样做。 abc->line will be pointing to the same memory address as p1 . abc->line将指向与p1相同的内存地址。

Or do I also need to free the area pointed by 'p1'?或者我还需要释放'p1'指向的区域吗?

No, you don't need to free both.不,您不需要同时释放两者。 You should either use:您应该使用:

free(abc->line);

or:或者:

free(p1);

You only need one of them, as both pointers are pointing to the same memory address, when you free one you free both.你只需要其中一个,因为两个指针都指向同一个内存地址,当你释放一个时,你释放两个。

Note that by freeing abc->line , p1 will become a dangling pointer, it will be pointing no nothing meaningful.请注意,通过释放abc->linep1将成为一个悬空指针,它将指向没有任何意义。

Recommended read regarding gets .关于gets推荐阅读

First, using gets() is not recommended.首先,不推荐使用gets() A good replacement is fgets() .一个很好的替代品是fgets()

How can I make 'line' point to the same string pointed by 'p1' without allocating >the same string twice?如何使“line”指向“p1”指向的同一个字符串而不分配>相同的字符串两次?

Two pointers can both point to the same buffer simply by setting them to point to the address of the buffer.两个指针都可以指向同一个缓冲区,只需将它们设置为指向缓冲区的地址即可。 Dynamic memory allocation is not necessary.不需要动态内存分配。 Given your code:鉴于您的代码:

//the following are created in file global scope
struct el{
    char *line;
    struct el *next;
};

struct el *abc, def; 

char *p1;
char buffer[100];

//The following is performed in local scope within a function, using global variables created above.
p1 = &buffer[0];//assign address of buffer to pointer p1
//same for char *line:
abc->line = &buffer[0];//assign address of buffer to member *line

//both will now accept input using fgets()
fgets(p1, sizeof(buffer), stdin);
fgets(abc->line, sizeof(buffer), stdin);

How can I make line point to the same string pointed by p1 without allocating the same string twice?如何在不分配相同字符串两次的情况下使line指向p1指向的同一个字符串? Is it enough to write abc->line = p1 ?abc->line = p1就够了吗?

Yes.是的。 abc->line = p1; is correct.是正确的。

Or do I also need to free the area pointed by p1 ?还是我还需要释放p1指向的区域?

No, not at all.一点都不。 In opposite, If you would do so, line would point to nowhere.相反,如果你这样做, line将指向无处。

Note that abc->line = p1;注意abc->line = p1; only assigned the value of the memory address of the chunk allocated by malloc() from p1 to the structure member line .只将malloc()p1分配的 chunk 的内存地址的值赋值给结构体成员line They both are references to the **same ** memory allocated by malloc() .它们都是对malloc()分配的 ** 相同 ** 内存的引用。


Never ever use gets() .永远不要使用gets() Reason why is here .原因在这里 It is also removed from the C standard since C11.自 C11 起,它也从 C 标准中删除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM