c - 如何解决C中的动态内存分配错误
问题描述
我正在尝试为用户输入动态分配内存。当我尝试使用 valgrind 运行程序时,我遇到了一些内存分配错误。这是消息:
==796== If you believe this happened as a result of a stack
==796== overflow in your program's main thread (unlikely but
==796== possible), you can try to increase the size of the
==796== main thread stack using the --main-stacksize= flag.
==796== The main thread stack size used in this run was 8388608.
这是main.c:
#include "functions.h"
int main(void) {
clear();
void (*funcptr)(void);
int option;
printf("=========================================Login or Create Account=========================================\n\n");
while(1) {
printf("Welcome to the Bank management program! Would you like to 1. Create Account or 2. Login?\n>>> ");
option = fgetc(stdin);
cleanStdinBuffer();
switch (option) {
case '1':
funcptr = create_account;
break;
case '2':
funcptr = login;
break;
default:
printf("\033[0;31m[ERROR] Invalid input. Please choose a valid option");
fflush(stdout);
print_dots(3);
printf("\n\033[0m");
continue;
}
break;
}
funcptr();
return 0;
}
当我尝试创建银行帐户时发生错误。但是,我还没有尝试登录。create account
functions.h 中函数的代码:
void create_account() {
clear();
char *username;
char *password;
printf("=========================================Create Account=========================================\n");
printf("Enter a username: ");
username = strmalloc(&username);
printf("Enter a password: ");
password = strmalloc(&password);
printf("%s is your username and %s is your password", username, password);
}
这是我用于动态分配内存的函数的代码,它也在functions.h中:
char *strmalloc(char **string) {
char *tmp = NULL;
size_t size = 0, index = 0;
int ch;
while ((ch = getchar()) != '\n' && ch != EOF) {
if (size <= index) {
size += 1;
tmp = realloc(*string, size);
if (!tmp) {
free(*string);
string = NULL;
break;
}
*string = tmp;
}
(*string)[index++] = ch;
}
return *string;
}
有谁知道发生了什么?
解决方案
您的代码过于复杂和错误。
- 字符串不是 NUL 终止的
- 您正在重新分配传递给函数的字符串。您只能重新分配通过
malloc
,realloc
或返回的东西calloc
。 - 您不需要将字符串的地址传递给
strmalloc
. 只需返回新分配的字符串。这会自动消除第 2 项的错误。
你要这个:
#include <stdio.h>
#include <stdlib.h>
char* strmalloc(void) {
char* string = malloc(1);
if (!string)
return NULL;
size_t size = 0, index = 0;
int ch;
while ((ch = getchar()) != '\n' && ch != EOF) {
if (size <= index) {
size += 1;
char *temp = realloc(string, size + 1); // + 1 for the NUL string terminator
if (!temp) {
free(string);
return NULL; // realloc failed return NULL straight away
}
string = temp;
}
string[index++] = ch;
}
string[index] = 0; // NUL terminator
return string;
}
int main()
{
char* x = strmalloc();
printf("x = %s\n", x);
free(x);
}
推荐阅读
- java - 执行程序以读取属性文件时找不到元素“bean”的声明
- freeradius - freeradius 3.0.13 使用自定义属性回复
- c - 什么是 C 中的模块?
- c# - 如何通过linq对列表进行分组并在数据表中显示内部列表
- vba - 循环遍历充满 excel 文件的文件夹中的特定工作表并提取为 .csv
- python - 记录的重复数据删除
- python-3.x - Networkx 错误:“在 _not_implemented_for 术语中 = {'directed': graph.is_directed()}”
- php - Google 云打印无法转换为 PDF
- wordpress - 如何在转发器字段中动态填充复选框值
- c# - .NetCore 2.x 关于使用 {*catchAll} 路由 URL.Action 总是返回 null