Reputation: 3
I am trying to create a basic program to implement Hamming code for my networking class
The program runs correctly for most cases but there are some specific cases where it breaks with -1073741819
The program takes a string of '0's and '1's as input
When the input string is of length of the form odd number ^ 2
an error occurs giving -1073741819 std::bad_alloc
All other cases seem to work
example input of 8 works, 10 works but of 9 doesn't work.
Similarly input of length 24 works, 26 works but 25 doesn't
Below is the code
It includes some code which does not give an error and I have marked when the irrelevant part starts.
#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<<"\n\nError at \n\n"<<errorAt;
}
==== END ====
*/
return 0;
}
While debugging with flags and basic debugging (printing where I am)I found that the program breaks in the second iteration of the marked loop
**While debugging new_allocator.h
open pointing at
void deallocate(pointer __p, size_type){ ::operator delete(__p); }
at the end of the program
I have tried
finaltoSend.append("0")
and also reserving memory before hand but none of the options work
Any hints would be greatly appreciated
Upvotes: 0
Views: 217
Reputation: 19721
You've actually got two errors in your code.
The first one is that you only reserve memory for the elements, but don't bring them into existence.
This is unlikely the reason for the behaviour you see (why you are technically writing into unused memory, that memory cannot be used by something else, however it's a latent bug waiting to happen when you further use your vector; also since int
s are PODs, they don't require a constructor to call, so you won't see problems due to uninitialized objects, which will change if you use the same wrong approach for vectors of other objects).
To actually bring those ints into existence, use resize
instead of reserve
.
The second bug is that you go outside even the reserved memory: You reserve space for totalLength
elements, but then write totalLength+1
elements. The last element writes beyond the reserved space, and is not unlikely to overwrite actual data used internally for memory management. Which given the error message is most likely what happened.
Note that this is the type of bug that is used by hackers to gain access to computer systems, by figuring out what is beyond that place, and replacing it with malicious stuff by specially crafted input. So consider yourself lucky that your code showed problems right away.
Upvotes: 2
Reputation: 3992
vector< int > toSend;
toSend.reserve(totalLength);
//...
for(int i=0;i<totalLength+1;i++){
// Say...what? --------^
toSend[i] = // different values on the two branches
Writing outside the reserved length?
Try using the
toSend.at(i)= // whatever
and see what the app will tell you at runtime. (hint: look at the difference between at and operator [] in respect with bounds check).
(see also why doesn't my program crash when I write past the end of an array? Hint: you can damage your memory and experience crashes much later: see the good-ol' fandango on core).
Upvotes: 4