[英]Valgrind invalid write of size 8
我正在嘗試使用C結構,但我想出了一個invalid write of size 8
然后從valgrind invalid read of size 8
消息。
我的代碼僅循環遍歷參數(如果argc > 1
),並且對於每個文件名,它將掃描string
和unsigned int
指示名稱和年齡(結構播放器)。
這是我到目前為止所擁有的所有代碼:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct player {
char name[20];
unsigned int age;
};
struct player *player_new_from_stream(FILE * stream){
struct player *new_player = (struct player*) malloc(sizeof(struct player));
char *p_name = malloc(20);
char *p_age = malloc(20);
if (stream != stdin){
if (fgets(p_name, 20, stream) != NULL){
char *p = strrchr(p_name, '\n');
if (p)
*p = '\0';
strcpy(new_player->name, p_name);
}
if (fgets(p_age, 20, stream) != NULL)
new_player->age = atoi(p_age);
}
else {
printf("enter name and age for a player\n");
gets(p_name);
gets(p_age);
strcpy(new_player->name, p_name);
new_player->age = atoi(p_age);
}
free(p_name);
free(p_age);
return new_player;
}
void player_inspect(struct player plyr, char* prefix){
printf("[%s] name: %s\n", prefix, plyr.name);
printf("[%s] age : %d\n", prefix, plyr.age);
}
int main(int argc, char* argv[]){
FILE * stream;
char* argument;
// below: trying to allocate (argc - 1) pointers
// valgrind's --show-origins=yes points here for both errors
struct player **players = malloc(sizeof(int) * (argc - 1));
int i = 1;
for (; i < argc; i++){
argument = argv[i];
if (strcmp("-", argument) != 0){
if ((stream = fopen(argument, "r")) == NULL) perror("Error opening file");
else {
// the next line emits Invalid write of size 8 in valgrind
players[i-1] = player_new_from_stream(stream);
fclose(stream);
}
} else {
players[i-1] = player_new_from_stream(stdin);
}
}
i = 0;
char buffer[15];
for (; i < argc - 1; i++){
sprintf(buffer, "%d", i);
// the next line emits Invalid read of size 8
player_inspect(*(players[i]), buffer);
free(players[i]);
}
free(players);
return 0;
}
怎么了 我想從player_new_from_stream
返回一個指向struct player
的指針,並將該指針打包到main()
數組players
。
這是錯誤的:
struct player **players = malloc(sizeof(int) * (argc - 1));
使用此代替:
struct player **players = malloc(sizeof(*players) * (argc - 1));
請注意,在您的系統上, sizeof(int) == 4
而sizeof(struct player *) == 8
。
如果要使用數組,則需要進行兩次分配:
struct player **players = malloc(sizeof(struct player*) * (argc - 1));
for (int i=0; i<argc-1;i++)
player[i] = malloc(sizeof(struct player));
我在valgrind下使用有效的輸入文件(播放器文件)運行了該文件,並使用gcc -g進行了編譯,但是它沒有給出任何這些無效的讀/寫消息。
它也適用於使用stdin。
但是,當我使用不存在的文件運行它時,它在讀取時出現錯誤
i = 0;
char buffer[15];
for (; i < argc - 1; i++){
sprintf(buffer, "%d", i);
player_inspect(*(players[i]), buffer); // <<HERE
free(players[i]);
}
由於players [i]指針為NULL,因為如果fopen調用失敗,則未設置該數組索引處的指針。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.