0

我的结构如下:

typedef struct
{
    char        *firstname;
    char        *lastname;
    char        *address;

} STUDENT;

并在主程序中

int main() {

 stud = (STUDENT *) calloc(1, sizeof(STUDENT));
//I have assinged some values to stud

}

我有另一个指针,它指向螺柱

STUDENT *abc;

abc = stud;

我没有像 abc 所指的那样释放螺柱。

现在我的问题是,在我可以访问 abc 但不能访问 stud 的另一个文件中,我想根据条件更新 stud->address

if(true) {
//update stud-> address
}

我怎么做?

好的,我忘了添加新值在函数末尾被释放:

 if(true) {
    //update stud-> address
      abc->address = xyz->address
    }
  free(xyz);

在这种情况下 abc->adress 将指向一个空内存对吗?在这种情况下如何更新 abc->address;

这会起作用吗:

 if(true) {
        //update stud-> address
          free(abc->address);
          abc->address = strdup(xyz->address);
        }
      free(xyz);
4

4 回答 4

1

现在我的问题是,在我可以访问abc但不能 访问的另一个文件中stud,我想根据条件更新 stud->address

if(true) {
//update stud-> address
}

我怎么做?

由于abc指向相同的地址stud,它们指向内存中的相同位置。其中任何一个都会将您带到存储数据的地方。

这部分:

 if(true) {
    //update stud-> address
      abc->address = xyz->address
    }
  free(xyz);

free(xyz)将释放内存位置abcxyz指向。但如果您分配->address. 如果是这样,它应该是这样的:

free(xyz->address);
// free any other allocated child elements
free(xyz);

这部分:

 if(true) {
        //update stud-> address
          free(abc->address);
          abc->address = strdup(xyz->address);
        }
      free(xyz);

也会出现内存泄漏。strdup分配内存并复制字符串,请参见此处

strdup() 函数应返回一个指向新字符串的指针,该字符串是 s1 指向的字符串的副本。返回的指针可以传递给 free()。如果无法创建新字符串,则返回空指针。

所以你还需要:

free(xyz->address);
// free any other allocated child elements
free(xyz);

如果需要做大量的引用和解引用,你可能需要实现一些简单的引用计数机制来管理引用。像这样简单的东西:

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

typedef struct {
    char        *firstname;
    char        *lastname;
    char        *address;
    unsigned int ref; // reference counter
} STUDENT;

// Create new object, and initialize it. Allocation should happen only here.
STUDENT* student_new(void) {
    STUDENT* obj = (STUDENT *) calloc(1, sizeof(STUDENT));
    // add one to the reference counter +1. So far, this object has
    // been used only once.
    if( obj ) obj->ref = 1;
    return obj;
}

// Get a references to and object, never use assignment `a = b`.
STUDENT* student_get_ref(STUDENT* obj) {
    // Rather than using `abc = stud`, use this function
    // to get a reference to and object. It will
    // increase the reference counter by one and
    // simply return `obj`.
    obj->ref++;
    return obj;
}

// Destroy the object and do some clean-up, never use `free` use it instead.
void student_destroy(STUDENT* obj) {
    // when the program is done from an object,
    // we decrease -1 the reference counter by one,
    // if the reference counter hit the 0,
    // this means no one is using this object,
    // so free it.
    printf("[DBG]: ref => %d\n", obj->ref);
    if( --obj->ref == 0 ) {
        printf("[DBG]: ref => 0, Object deleted\n");
        free(obj);
    }
}

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

    STUDENT *stud = student_new();
    STUDENT *abc;
    STUDENT *xyz;

    abc = student_get_ref(stud);
    xyz = student_get_ref(abc);

    student_destroy(stud);
    student_destroy(abc);
    student_destroy(xyz);

    return 0;
}

如果你运行它,你会看到内存直到 才被释放studabc并且xyz都完成了:

> example.exe
[DBG]: ref => 3
[DBG]: ref => 2
[DBG]: ref => 1
[DBG]: ref => 0, Object deleted

>

此外,它是一种更简洁的内存管理方式,错误更少,所有分配仅在构造函数student_new中完成,释放在析构函数中完成student_destroy。您的程序不再需要调用calloc// mallocfree

于 2013-08-27T19:22:20.207 回答
0

如果两个指针都指向同一个内存,那么使用哪一个来更改结构中的值并不重要,它总是会被修改。

因此,在您的其他文件中,您可以简单地使用:

abc->address = something;

它将被更新。当您使用另一个指针stud时,它将显示您所做的更改。

于 2013-08-27T17:49:57.070 回答
0

abcstud存储相同的值,即malloc/calloc.

C 语法abc->lastname只是查找内存地址,lastname以便您可以读/写它。

因此,您只需使用abc->(<fields>)写入,程序的其他部分就可以读取更新后的值。

我假设您只有一个线程进行读/写,多线程 I/O 是另一种野兽。

于 2013-08-27T17:53:09.807 回答
0

如果您有权访问 abc。然后你可以这样做:

if(true) {
   abc->address = something_new_value; //update stud-> address
}

正如其他人在动态分配内存时指出的那样,它应该可以直接从其他文件访问,因为 calloc() 分配的内存不是来自堆栈。但这样做并不一定是一种好的编码习惯,因为您可能会忘记哪个模块在何时何地访问内存。

于 2013-08-27T17:53:19.863 回答