在使用C++字符串时对特定输入获取bad_alloc

Getting bad_alloc on specific inputs while using C++ strings

本文关键字:输入 获取 bad alloc C++ 字符串      更新时间:2023-10-16

我正在尝试创建一个基本程序来为我的网络类实现Hamming代码

该程序在大多数情况下都能正确运行,但在某些特定情况下,它会与-1073741819 发生冲突

程序采用字符串"0"answers"1"作为输入

当输入字符串的长度为形式odd number ^ 2时,会出现一个错误,给出-1073741819 std::bad_alloc

所有其他情况似乎都有效
示例输入8个作品,10个作品,但9个作品不起作用
类似地,长度为24的输入有效,26有效,但25不

以下是代码
它包括一些不会给出错误的代码,我已经标记了无关部分何时开始。

#include<iostream>
#include<cmath>
#include<vector>
using namespace std;
int main(){
string data;
cout<<"Enter data to send => :n";
cin>>data;
int len = data.length();
int maxPowerOfTwo = log2(len-1) + 1;
int totalLength = len +  maxPowerOfTwo + 1;
vector< int > toSend;
toSend.reserve(totalLength);
toSend[0] = 0;
int l = 0;
int k = 0;
for(int i=0;i<totalLength+1;i++){
    if(l==i){
        toSend[i] = 0;
        if(l==0){
            l++;
        }
        else{
            l*=2;
        }
    }
    else{
        toSend[i] = data[k]-48;
        k++;
    }
}
int currentPower = 0;
int startPosition = 1;
for(;currentPower<maxPowerOfTwo+1;currentPower++){
    int tempSum = 0;
    int tempCounter = 0;
    for(int currentPosition = startPosition;currentPosition<totalLength+1;){
        tempSum = tempSum + toSend[currentPosition];
        tempCounter++;
        if(tempCounter==startPosition){
            currentPosition += startPosition + 1;
            tempCounter = 0;
        }
        else{
            currentPosition++;
        }
    }
    if(tempSum%2!=0){
        toSend[startPosition] = 1;
    }
    else{
        toSend[startPosition] = 0;
    }
    startPosition*=2;
}
string finaltoSend;
for(int i=1;i<=totalLength;i++){ // MARKED LOOP
    if(toSend[i]==0){
        finaltoSend.push_back('0');
    }
    else{
        finaltoSend.push_back('1');
    }
}
/*
==== NOT RELEVANT ====
cout<<"nData to send => "<<finaltoSend<<'n';
string received = finaltoSend;
cout<<"nEnter data received of length "<<totalLength<<'n';
cin>>received;
int t_len = received.length();
int t_maxPowerOfTwo = log2(t_len-1);
int t_currentPower = 0;
int t_startPosition = 1;
int errorAt = -1;
for(;t_currentPower<t_maxPowerOfTwo+1;t_currentPower++){
    int tempSum = 0;
    int tempCounter = 0;
    for(int currentPosition = t_startPosition;currentPosition<t_len+1;){
        tempSum = tempSum + received[currentPosition-1] - 48;
        tempCounter++;
        if(tempCounter==t_startPosition){
            currentPosition += t_startPosition + 1;
            tempCounter = 0;
        }
        else{
            currentPosition++;
        }
    }
    if(tempSum%2!=0){
        errorAt+=t_startPosition;
    }
    t_startPosition*=2;
}
if(errorAt == -1){
    cout<<"nNo error";
}
else{
    errorAt++;
    cout<<"nnError at nn"<<errorAt;
}
==== END ====
*/
return 0;
}

在使用标志进行调试和基本调试(打印我所在的位置(时,我发现程序在标记循环的第二次迭代中中断

**调试指向的new_allocator.h打开时程序末尾的void deallocate(pointer __p, size_type){ ::operator delete(__p); }

我试过了finaltoSend.append("0"),并在手之前保留内存,但所有选项都不起作用

任何提示都将不胜感激

vector< int > toSend;
toSend.reserve(totalLength);
//...
for(int i=0;i<totalLength+1;i++){
  // Say...what? --------^
  toSend[i] = // different values on the two branches

超出预留长度书写?

尝试使用

  toSend.at(i)= // whatever

看看应用程序在运行时会告诉你什么。(提示:看看at和运算符[]在边界检查方面的区别(。

(另请参阅为什么当我写过数组末尾时,我的程序不会崩溃?提示:你可能会损坏你的内存,并在很久以后经历崩溃:请参阅内核上的好的ol'fandango(。

您的代码中实际上有两个错误。

第一个是,你只为元素保留内存,但不让它们存在。

这不太可能是你所看到的行为的原因(为什么从技术上讲,你正在向未使用的内存中写入,该内存不能被其他东西使用,但当你进一步使用向量时,这是一个潜在的错误;此外,由于int是POD,它们不需要调用构造函数,所以你不会看到由于未初始化对象而导致的问题,如果你对其他对象的向量使用相同的错误方法,这种情况就会改变(。

要真正实现这些int,请使用resize而不是reserve

第二个错误是,您甚至超出了保留内存:您为totalLength元素保留了空间,但随后写入了totalLength+1元素。最后一个元素的写入超出了保留空间,并且不太可能覆盖内部用于内存管理的实际数据。给出错误消息的最有可能是发生了什么。

请注意,这是黑客用来访问计算机系统的一种错误,通过找出超出该位置的内容,并通过特制的输入用恶意内容替换它。因此,您应该认为自己很幸运,您的代码立即显示了问题。