我不確定如何使用C語言中的以下stucts來存盤和修改int。我認為我插入到學生結構中的值并沒有被存盤。學生的成績必須保持void*,我需要隨時訪問/修改成績,直至退出。
typedef struct student{>
void *grade;
} student;
typedef struct school{>
學生 **學生。
size_t school_size。
}school;
學生 *student_create(int x) {
student *new_student = malloc(sizeof(student))。
new_student->grade = malloc(sizeof(int)>。)
new_student->grade = &x;
return new_student;
}
學校 *school_create(size_t school_szie) {
school *s = (school*)malloc(sizeof(school))。
s->students = (student**)malloc(sizeof(student*)* school_szie)。
for (int i = 0; i < school_szie; i) {
s->students[i] = NULL;
}
return s;
}
void school_insert(學校*s, int count, int index){
if(s->students[index] == NULL){
student *new_s = student_create(count)。
s->students[index] = new_s;
}
}
void student_inc(school *s, int index){
*(int *)s->students[index]->grade = *(int *)s-> students[index]-> grade 1;
}
int main(){
int a = 10;
void *ptr = &a;
printf("%d
"/span>, *(int *)ptr)。
*(int *)ptr = *(int *)ptr 1;
printf("%d
", *(int *)ptr)。
學校 *s1 = school_create(5)。
school_insert(s1, 2, 1); //學校名稱,年級,索引。
school_insert(s1, 4, 0) 。
school_insert(s1, 7, 3) 。
printf("%d
", *(int *)s1->學生[1]->年級)。
printf("%d
", *(int *)s1->學生[0]->成績)。
printf("%d
", *(int *)s1->學生[3]->成績)。
return 0;
}
我得到了以下輸出,盡管最后三行的預期輸出應該是2、4、7。
10
11
7
7 7
7 7
uj5u.com熱心網友回復:
有幾個問題。請看注釋行。
#include <stdio.h>/span>
#include <stdlib.h>
typedef struct student {
void* grade;
} student;
typedef struct school {
學生**學生。
size_t school_size。
}school;
student* student_create(int x) {
student* new_student = malloc(sizeof(student))。
new_student->grade = malloc(sizeof(int) )。)
*(int*)(new_student->grade) = x; // changed
return new_student;
}
學校* school_create(size_t school_szie) {
school* s = (school*)malloc(sizeof(school))。
s->students = (student**)malloc(sizeof(student*)* school_szie)。
for (size_t i = 0; i < school_szie; i) {
s->students[i] = NULL;
}
s->school_size = school_szie; //你忘記了這個。
return s;
}
void school_insert(school* s, int count, int index) /span> {
if (s->students[index] == NULL) {
學生* new_s = student_create(count)。
s->students[index] = new_s;
}
}
void student_inc(學校* s, int index) {
*(int*)s->students[index]->grade = *(int*)s->students[index]->grade 1;
}
int main() {
int a = 10;
void* ptr = &a;
printf("%d
"/span>, *(int*)ptr)。
*(int*)ptr = *(int*)ptr 1;
printf("%d
", *(int*)ptr)。)
學校* s1 = school_create(5)。
school_insert(s1, 2, 1); //學校名稱,年級,索引。
school_insert(s1, 4, 0) 。
school_insert(s1, 7, 3) 。
printf("%d
", *(int*)(s1->students[1]->grade)); // changed
printf("%d
", *(int*)(s1->students[0]->grade)); // changed
printf("%d
", *(int*)(s1->students[3]->grade)); // changed
return 0;
}
這沒有意義,原因有二:
這沒有意義。
new_student->grade = malloc(sizeof(int)>。)
new_student->grade = &x;
new_student->grade = &x覆寫了已經在前一行分配的new_student->gradenew_student->grade = &x將本地變數x的指標放入new_student->grade,但是一旦student_create函式結束,這個區域變數將不復存在。
你想。*(int*)(new_student->grade) = x;。你在main的開頭使用a和ptr的測驗已經做對了。
你忘了在
school_create中指定學校的大小。
s->school_size = school_szie; // you forgot this.
這是不對的:
printf("%d
", s1->學生[1]->年級)。)
s1->students[1]->grade是指向成績的指標,但你想要的是成績本身。在這里,你假裝s1->students[1]->grade實際上是一個int,并且printf將其列印為一個int。這是未定義的行為,列印的值可以是任何垃圾值。
因此,你需要*(int *)s1->students[1]->grade。(int *)將指向void的指標轉換為指向int的指標,而*則解除對指向int的指標的參考。
最后,你應該在這個for回圈中使用
size_t而不是int:
for (size_t i = 0; i < school_szie; i)
school_szie是一個size_t。
然而這最后一個問題對這里的程式輸出沒有影響。
既然如此,請注意在struct student中使用void *grade對我來說是非常、非常糟糕的設計(如果不是更糟的話)。它應該是int grade。你想存盤一個成績。
另外,結構中的學生應該是int grade。
另外,struct student應該至少包含一個學生名字或一些學生識別符號。
uj5u.com熱心網友回復:
我用gcc -g main.c -o main編譯了你的程式,并用valgrind ./main運行了它,很快發現了記憶體問題。試試吧!
Valgrind抱怨說,最后3個printf陳述句的條件跳轉取決于未初始化的值。這意味著這三個等級沒有被初始化。
雖然花了一些時間去挖掘,但還是找到了問題所在。它是在:
student *student_create(int x){
student *new_student = malloc(sizeof(student))。
new_student->grade = malloc(sizeof(int)>。)
new_student->grade = &x;
return new_student;
}
你真正想要的是*(int*)new_student->grade = x,它將x寫到新分配的記憶體位置。
uj5u.com熱心網友回復:
好吧,這并沒有什么意義:
new_student->grade = malloc(sizeof(int)>。)
new_student->grade = &x;
記憶體被分配并分配給new_student->grade,然后迅速被一個引數的指標所覆寫。所以你現在有一個記憶體泄漏(你再也無法釋放所分配的記憶體)和未定義的行為,因為在函式回傳后,指向區域變數的指標不再有效。
你要做的是分配一個整數,給它賦值,然后把它的指標分配給new_student->grade。
int *grade = malloc(sizeof *grade)。
if (! grade) {
//正確處理錯誤(這里不顯示)。
return NULL。
}
*grade = x;
new_student->grade = grade。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/315453.html
標籤:
上一篇:如何在jetpackcompose中更改BasicTextField的backgorundColor?
下一篇:值沒有被分配給連續的地址
