簡體   English   中英

從另一個指向第一個指針的指針更改一個指針的值

[英]change the value of a pointer from another pointer which is pointing to the first pointer

我的結構如下:

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);

現在我的問題是,在另一個我可以訪問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;
}

如果運行它,您將看到直到studabcxyz都用完后才釋放內存:

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

>

此外,這是一種更干凈的內存管理方式,減少了錯誤,所有分配僅在構造函數student_new中完成,而釋放在析構函數student_destroy完成。 您的程序不再需要調用calloc / malloc / free

如果兩個指針都指向同一個內存,則沒關系,無論您使用哪個指針來更改結構中的值,都將始終對其進行修改。

因此,在您的其他文件中,您可以輕松使用:

abc->address = something;

它將被更新。 當您使用另一個指針stud ,它將顯示您所做的更改。

abcstud存儲相同的值,即malloc/calloc的內存地址。

C語法abc->lastname只是仰望的內存地址, lastname ,所以你可以讀/寫它。

因此,您只需使用abc->(<fields>)進行寫入,程序的另一部分即可讀取更新后的值。

我假設您只有一個線程在進行讀/寫,而多線程I / O是另一種野獸。

如果您有權訪問abc。 然后,您可以執行以下操作:

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

正如其他人指出的那樣,當您動態分配內存時,也應該可以從其他文件直接訪問它,因為calloc()分配的內存不是來自堆棧。 但是這樣做並不一定是一種好的編碼習慣,因為您可能會不清楚哪個模塊在何時何地訪問內存。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM