如何在c ++中调整数组大小时修复错误?
How to fix an error when resizing array in c++?
我有一个返回一行输入字符的小程序:
#include <iostream>
char *resize(const char *str, unsigned size, unsigned new_size);
char *resize(const char *str, unsigned size, unsigned new_size)
{
char * m = new char[new_size];
for (int i = 0; i < size && i < new_size; ++i) {
m[i] = str[i];
}
delete [] str;
return m;
}
char *getline()
{
char ch;
std::cin >> ch;
int size = 1;
char * str = new char[size];
char * m;
while (std::cin.get(ch) && ch != 'n') {
str[size-1] = ch;
m = resize(str, size, ++size);
m[size] = ' ';
}
return m;
}
但它给了我一个错误:
测试 #1 失败。引发 "std::logic_error"的实例 what():内存泄漏或双倍 发生分配 已中止(核心转储)
我不完全明白问题出在哪里,因为我是C++新手。如何解决问题?
这里有一个问题:m = resize(str, size, ++size);
.函数参数的计算顺序未指定,因此允许编译器在将size
的值作为第二个参数传递之前递增size
。将代码重写为m = resize(str, size, size+1); ++size;
.
让我们分析一下我对代码所做的一些小改动:
while (std::cin.get(ch) && ch != 'n') {
str[size - 1] = ch;
int newSize = size + 1;
m = resize(str, size, newSize);
m[newSize - 1] = ' ';
str = m;
size = newSize;
}
在您执行m[size]
之前,但在调整大小后size
已经超出了边界。
正如皮特·贝克尔(Pete Becker)所指出的,函数参数的求值顺序是未指定的
在第一次迭代结束时,str
指向已释放的内存(您在调整大小调用中释放它),我相信您想用指针覆盖它m
.
如注释中所述,在生产代码中,您可能希望使用std::string
或std::vector
,或者通常使用一些封装调整大小行为的类。
最后,如果您从未进入循环,则m
不会初始化,并且您将返回垃圾未初始化的指针。考虑初始化为nullptr
。
此语句
std::cin >> ch;
是多余的。该字符不会存储在任何地方。因此,如果必须省略第一个字符时该行没有特殊格式,则应删除此语句。如果要通过以前的某些输入操作删除存储在输入缓冲区中的换行符,则应在调用该函数的代码中执行此操作。
此循环存在几个问题。
while (std::cin.get(ch) && ch != 'n') {
str[size-1] = ch;
m = resize(str, size, ++size);
m[size] = ' ';
}
对于初学者,应初始化分配的数组
char * str = new char[size]{};
否则,如果用户输入的第一个字符将是换行符,则数组仍将未初始化。
正如在其他答案中已经指出的那样,计算函数参数的顺序是未指定的。所以这个电话
m = resize(str, size, ++size);
^^^^ ^^^^^^
导致未定义的巴哈维。
其次,指针str
在循环中不会更改。另一方面,它在被调用函数resize
内的循环的第一次迭代中删除。
此声明
m[size] = ' ';
尝试访问超出已分配阵列的内存。
例如,可以通过以下方式重写循环
int size = 1;
char * str = new char[size]{};
while (std::cin.get(ch) && ch != 'n')
{
str[size-1] = ch;
str = resize( str, size, size + 1);
str[size++] = ' ';
}
return str;
您正在访问m[size] = ' ';
中的越界元素 应该是m[size-1] = ' ';
这个char* m
是没有用的,只需使用str
,当你调用resize
编译器的参数计算顺序是未知的,所以这样做
unsigned newSize=size+1;
str = resize(str, size, newSize);
size=newSize;
代码可以变成这样:
#include <iostream>
char *resize(const char *str, unsigned size, unsigned new_size)
{
char * m = new char[new_size];
for (int i = 0; i < size && i < new_size; ++i)
{
m[i] = str[i];
}
delete [] str;
return m;
}
char *getline()
{
char ch;
int size = 1;
char * str = new char[size];
while (std::cin.get(ch) && ch != 'n')
{
str[size-1] = ch;
unsigned newSize=size+1;
str = resize(str, size, newSize);
size=newSize;
str[size] = ' ';
}
return str;
}
int main()
{
std::cout << getline() << std::endl;
return 0;
}
但我建议只使用std::string
,因为这段代码不是最有效或最好看的。
- 警告处理为错误这里有什么问题
- 当我选择大于 720 的矩阵大小时,程序退出并显示错误代码.可能是什么原因?
- 尝试使用 EvtSetChannelConfigProperty() 函数更新最大事件日志文件大小时插入的错误值
- 当 std 数组初始化太小时,C++会引发错误吗?
- 如何在c ++中调整数组大小时修复错误?
- 使用 Nvidia NPP 调整图像大小时未记录的大小调整错误
- 我在 36603 以上输入的任何数组大小时都会返回"堆栈溢出"错误。如何使字符串能够捕获整个.txt文件?
- 调整数组大小时出现内存错误
- 当整数变量用于在 c++ 中声明数组大小时,错误显示为"Expression must have a const value"
- 为什么此代码在使用可变数组大小时不会生成错误?
- Qt QQuickView视觉错误/调整大小时闪烁
- 增加数组大小时 CUDA 主体磁贴计算错误代码 77
- 调整矢量大小时出现运行时错误
- 重新调整优先级队列大小时出现双重释放或损坏错误
- 用ctime转换为char*时,std chrono 1小时错误
- 通过指定返回值的大小时出现质量错误
- 将time_t转换为字符串,而将字符串转换为time_t会给出错误的年份和小时
- 调整大小时出现Std::vector和内存错误
- 程序运行正常数小时,最终通过内存地址0x10出现 Seg 错误
- 使用SDL2调整无边框窗口大小时的错误