Program crash on array index assignment - c++

I'm having a little problem here.
Every time I run the code below, my program just crash.
void Wingcod::push(byte b)
{
stack[stackp] = b;
stackp++;
if(stackp >= stacks)
{
stacks += 16;
try
{
realloc(stack,stacks);
}catch(bad_alloc*)
{
cerr << "STACK OVERFLOW";
exit(1);
}
}
}
And stack, stackp and stacks is defined like this:
stacks = 8;
stackp = 0;
stack = new byte[stacks];
And byte is just a unsigned char.

You're not allowed to use realloc() on a pointer that was allocated with new.
Maybe try something like the following instead of realloc():
byte* tmp = new byte[stacks];
delete [] stack;
stack = tmp;

realloc doesn't throw exceptions as it's not related to new, but C's malloc. It also doesn't set the pointer.
stacks = 8;
stackp = 0;
stack = static_cast<byte*>(malloc(stacks * sizeof(byte)));
void Wingcod::push(byte b)
{
stack[stackp] = b;
stackp++;
if(stackp >= stacks)
{
stacks += 16;
if(!(stack = static_cast<byte*>(realloc(stack,stacks * sizeof(byte))))) {
cerr << "STACK OVERFLOW";
exit(1);
}
}
}

You cannot use a pointer allocated with new T[n] as an argument for realloc(). The pointers working with realloc() have to come from the malloc() family of functions (malloc(), calloc(), or realloc()). Personally, I wouldn't use any of this but rather use std::vector<T>.

From here, Realloc only works on a pointer to memory previously assigned by alloc. Try using malloc

Related

Is it safe to delete a void* byte by byte?

Because i don't know verry much about memory allocation, I would like to know if it safe to delete a block of consecutive bytes (array) like this.
void Free(void* ptr, size_t cbSize)
{
if (cbSize == 0) return;
if (ptr == NULL) return;
for(size_t i = cbSize; i > 0; i--)
{
char* p = &((char*)ptr)[i];
delete p;
}
char* p = (char*) (ptr);
delete p;
}
I have tried this method in the following circumstances and got no error.
int* a = new int[100];
Free(a, 100 * sizeof(int));
int* a = (int*) malloc(100 * sizeof(int));
Free(a, 100 * sizeof(int));
You always delete what you allocate; exactly and only what you allocate. If you new a single thing, you delete a single thing. The fact that the "single thing" happens to take up more than one byte is irrelevant; you delete what you new.
How can i make my function work in this case ?
You don't. You newed an array of ints. So you must delete an array of ints. Types matter in C++.

C++ Memory Allocation/Deallocation & FreeSpace Bug Error

I am practicing memory allocation and disk management with C++. I just all of the work.. it just looks and seem's a little too easy. I am not sure if my pointer and my allocation and deallocations are correct. My Total FreeSpace looks like it will work, but it looks too basic. I just need someone's programming experience. When I try to run this code it gives me some kind of Error.
Bug Error
Please DO NOT ADD any new Global Variable.
const int MMSIZE = 60136;
char MM[MMIZE];
//** Initialize set up any data needed to manage the memory
void initializeMemory(void)
{
//**increments through the POOL_SIZE
for (int a = 0; a < MMSIZE; a++) {
MM[a] = 'NULL';
}
}
// return a pointer inside the memory
// If no chunk can accommodate aSize call onOutOfMemory()
void* allocate(int size)
{
//******NOT SURE*******
int *p = new int;
*p = 5;
return ((void*) 0);
}
// Free up a chunk previously allocated
void deallocate(void* mPointer)
{
//******NOT SURE*******
int *p = new int;
delete p;
p = 0;
p = new int(10);
}
//Scan the memory and return the total free space remaining
int remaining(void)
{
//******NOT SURE*******
int free = 0;
for (int a = 0; a < MMSIZE; a++)
{
if (MM[a] < MMSIZE)
{
free += a;
}
}
int free2 = free - MMSIZE;
return free2;
}
This code looks unfinished for even a sample but
//** Initialize set up any data needed to manage the memory
void initializeMemory(void)
{
//**increments through the POOL_SIZE
for (int a = 0; a < MMSIZE; a++) {
MM[a] = 'NULL';// <=== this should not even compile as the single quote should only take one character like '\x0' or 'N'
}
}
should not even compile as the single quote should only take one character like '\x0' or 'N'
but post the complete module and i can help you more and maybe explain a few things.
Without discussing other aspects of your code (such as memory leaking etc), the specific error you are getting most likely comes from *int_pointer = 0xDEADBEEF; line. int_pointer is equal to 0, because int_pointer = (long *)allocate(sizeof(long)); and your void* allocate(int size) with its return ((void*) 0); always returns 0. So you are getting exactly that exception: attempting to write 0xDEADBEEF at address 0x00000000, which is a forbidden operation (there is some OS specific stuff at low addresses).

Custom string implementation, operator + overload memory allocation issue

I am trying to create custom string implementation in c++ and I have a problem with overloading operator "+". I want to append new string to existing one and when I try to allocate a new extended string, debugger allocates around 12 bytes more then it should. I have no control over allocation, he just ignores variable "length". Here is the code:
class String
{
private:
char *ptrNiz;
public:
String(const char *niz = "")
{
ptrNiz = new char[strlen(niz)+1];
strcpy_s(ptrNiz, strlen(niz)+1, niz);
cout << "stvoren niz: " << ptrNiz << endl;
}
String(const String& refString)
{
ptrNiz = new char[strlen(refString.ptrNiz) + 1];
strcpy_s(ptrNiz, strlen(refString.ptrNiz) + 1, refString.ptrNiz);
cout << "Kopiran niz: " << ptrNiz << endl;
}
~String()
{
cout << "Unisten objekt: " << ptrNiz << endl;
delete[] ptrNiz;
}
int Length() const
{
return strlen(ptrNiz);
}
int CharAt(int i) const
{
return ptrNiz[i];
}
void Ispisi()
{
cout << ptrNiz << endl;
}
operator char*()
{
return ptrNiz;
}
String operator+=(const const String& ref)
{
const int const length = ref.Length() + this->Length() + 1;
char *temp = new char[length]; // ignores length and allocates more space
for (int i = 0; i < this->Length(); i++)
{
temp[i] = ptrNiz[i];
}
for (int j = 0; j < ref.Length(); j++)
{
temp[this->Length() + j] = ref.ptrNiz[j];
}
return String(temp);
}
};
char *temp = new char[length]; // ignores length and allocates more space
All which your C++ implementation is required to do here is returning a pointer to a memory location with room for length bytes. Nothing more, nothing less. It is allowed to internally allocate more bytes, even though your code must not try to access them (or else the behaviour is undefined).
The low-level details of dynamic memory allocation is an implementation issue, not your code's concern.
A debug build is a very good example for a situation in which a C++ implementation may use extra bytes for debugging information. In fact, that's probably what is happening here. I suppose you are using Visual C++. As its documentation (CRT Debug Heap Details) says:
When you request a memory block, the debug heap manager allocates from
the base heap a slightly larger block of memory than requested and
returns a pointer to your portion of that block.
[...]
The additional memory allocated by the debug heap routines is used for
bookkeeping information, for pointers that link debug memory blocks
together, and for small buffers on either side of your data to catch
overwrites of the allocated region.
Note that there are very many other grave errors in your code. I decided to ignore them for now and just answered the exact question you asked.
You are allocating twice, once in the constructor and again in the operator+= method. You also aren't deleting the pointer in the operator function so that memory is leaking. Either use smart pointers or provide an additional constructor parameter which specifies the ownership of the incoming pointer.
In your code please add the following line in to terminate the string with NULL;
String operator+=(const const String& ref)
{
// You code goes here
temp[length - 1] = '\0';
return String(temp);
}
This will work as expected.
Hope this helps.

C++ Where is the seg fault?

I am currently tackling this assignment for my computer science class:
Make your own dynamic array template. It should allow creating contiguous arrays (filled with things of the same type) which you can extend without worrying about running out of space.
Do one version using malloc and free.
Do one version using new and delete.
My version using new and delete works flawlessly; however, in trying to convert my new/delete code to using malloc/free, I keep getting a seg fault. I have narrowed down the segfault (I think), to being in a single function: addData. Take a look at the code in my main I used to test this:
Array2<int> *testArray3 = new Array2<int>(5);
Array2<int> *testArray4;
testArray3->initArray();
testArray3->printArray();
testArray4 = testArray3->addData(7);
testArray4->printArray();
return 0;
This gives a seg fault; however, when I change it to this:
Array2<int> *testArray3 = new Array2<int>(5);
Array2<int> *testArray4;
testArray3->initArray();
testArray3->printArray();
testArray4 = testArray3; //->addData(7);
testArray4->printArray();
return 0;
There is no seg fault. This makes me believe the issue is in my addData function. Here is the code for that:
Array2<T> *addData(T dataToAdd){
Array2 <T> *tmp;
tmp->data = this->getData();
Array2 <T> *newData;
newData->data = (T *) malloc(sizeof(T)*(this->size + 1));
for (int i = 0; i < tmp->getSize() + 1; ++i){
if (i < tmp->getSize()){
//newData->data[i] = tmp->data[i];
newData->setData(tmp->getData()[i], i);
}
else{
//newData->data[i] = dataToAdd;
newData->setData(dataToAdd, i);
}
}
free(tmp->data);
free(this->data);
return newData;
};
I am new to programming as a whole and have not completely wrapped my head around pointers and memory allocation, etc. Any advice you could give me would be greatly appreciated! In case you need to see the rest of the code, here is the entire file I coded my template in. Thank you so much for your time!
#include <iostream>
#include <string>
#include <cstdlib>
#include <sstream>
using namespace std;
template<typename T>
class Array2{
public:
Array2(int size){
this->size = size;
data = (T *) malloc(sizeof(T)*size);
};
Array2<T> *addData(T dataToAdd){
Array2 <T> *tmp;
tmp->data = this->getData();
Array2 <T> *newData;
newData->data = (T *) malloc(sizeof(T)*(this->size + 1));
for (int i = 0; i < tmp->getSize() + 1; ++i){
if (i < tmp->getSize()){
//newData->data[i] = tmp->data[i];
newData->setData(tmp->getData()[i], i);
}
else{
//newData->data[i] = dataToAdd;
newData->setData(dataToAdd, i);
}
}
free(tmp->data);
free(this->data);
return newData;
};
~Array2(){
free(this->data);
};
void initArray(){
for (int i = 0; i < this->size; ++i){
//this->data[i] = i;
this->setData(i, i);
}
};
void printArray(){
//ostringstream oss;
string answer = "";
for (int i = 0; i < this->size; ++i){
//oss << this->data[i] + " ";
cout << this->data[i] << " ";
}
//answer = oss.str();
cout << answer << endl;
};
T* getData(){
return this->data;
}
int getSize(){
return this->size;
}
void setData(T data, int index){
this->getData()[index] = data;
}
private:
int size;
T* data;
};
Array2 <T> *tmp;
Allocates a pointer. This does not point the pointer at anything or allocate any storage for the pointer to point at. What it points at without being explicitly assigned is undefined. If you are lucky, and you are this time, tmp points at an invalid location and the program crashes. If you are unlucky, tmp points at some usable region of program memory and lets you write over it, destroying whatever information was there.
tmp->data = this->getData();
Attempts to access the data member at tmp, but fortunately for you the access is in invalid memory and the program comes to a halt. It also has tmp's data pointing at this's data, and that's a dangerous position to be in. Changes to one will happen to the other because they both use the same storage. Also think about what will happen to this->data if you free tmp->data.
Or perhaps I'm wrong and the halt is here for the same reason:
Array2 <T> *newData;
newData->data = (T *) malloc(sizeof(T)*(this->size + 1));
Both need to be fixed. tmp doesn't have to live long, so we can make it a temporary local variable.
Array2 <T> tmp;
Typically this will be created on the stack and destroyed when the function ends and tmp goes out of scope.
But this will not work because Array2's constructor requires a size so it can allocate the array's storage. You need to find out how big to make it. Probably something along the lines of:
Array2 <T> tmp(this->size + 1);
But frankly I don't think you need tmp at all. You should be able to copy the dataToAdd directly into newData without using tmp as an intermediary.
newData is eventually going to be returned to the caller, so it needs a longer scope. Time to use new.
Array2 <T> *newData = new Array2 <T>(this->size + 1);
And through the magic of the constructor... Wait a sec. Can't use new. That makes this hard. malloc doesn't call constructors, so while malloc will allocate resources for newData, it doesn't do the grunt work to set newData up properly. Rule of thumb is Never malloc An Object. There will be exceptions I'm sure, but you shouldn't be asked for this. I recommend using new here and politely telling the instructor they are on crack if they complain.
Anyway, new Array2 <T>(this->size + 1) will allocate the data storage for you with it's constructor.
There is an easier way to do this next bit
for (int i = 0; i < tmp->getSize() + 1; ++i){
if (i < tmp->getSize()){
//newData->data[i] = tmp->data[i];
newData->setData(tmp->getData()[i], i);
}
else{
//newData->data[i] = dataToAdd;
newData->setData(dataToAdd, i);
}
}
Try:
for (int i = 0; i < tmp->size; ++i){
newData->data[i] = tmp->data[i]; // you were right here
}
newData->data[tmp->size] = dataToAdd;
And back to something I hinted at earlier:
free(tmp->data);
free(this->data);
Both tmp->data and this->data point to the same memory. To be honest I'm not sure what happens if you free the same memory twice, but I doubt it's good. Regardless, I don't think you want to free it. That would leave this in a broken state.
Recap and fixes
Array2<T> *addData(T dataToAdd)
{
Array2 <T> *newData = new Array2 <T>(this->size + 1);
for (int i = 0; i < this->size; ++i)
{
newData->data[i] = this->data[i];
}
newData->data[this->size] = dataToAdd;
return newData;
};
This version leaves this intact and returns a newData that is one bigger than this. What it doesn't do is add anything to this. Which is goofy for a method named addData.
It also leads to stuff like this:
mydata = myData->addData(data);
which leaks memory. The original mydata is lost without deletion, resulting in a memory leak.
What I think you really need is a lot simpler:
Array2<T> & addData(T dataToAdd)
{
this->data = realloc(this->data, this->size + 1);
this->data[this->size] = dataToAdd;
this->size++;
return *this;
};
realloc effectively allocates a new buffer, copies the old buffer into the new one, and frees the old buffer all in one fell swoop. Groovy.
We then add the new element and increment the count of elements stored.
Finally we return a reference to the object so it can be used in a chain.
Usage can be
myData.addData(data);
myData.addData(data).addData(moredata);
myData.addData(data).printArray();
and if you have operator << support written
std::cout << myData.addData(data) << std::endl;
I'd go back over the new version of Array if I were you. Most of the bugs picked off here are conceptual errors and also apply to it. You might just be getting unlucky and it merely looks like it works. I just read C++ Calling Template Function Error. The posted solutions fixed the immediate problem, but did not touch the underlying memory management problems.
As for the rest of your class, I advice following the link and answering What is The Rule of Three? Because Array2 violates the heck out of it.

Does this code leak if use of function relace1() doesn't delete memory allocated by cc?

I think this code leaks, unless outside replace1() somebody deletes the memory allocated by cc = new[....], can you confirm??
char* replace1(char *c){
if(c == NULL) return NULL;
int len = strlen(c);
if(len == 0) return NULL;
int cnt = 0;
for(int i=0; i<len; ++i)
{
if(c[i] == ' ')
++cnt;
}
char *cc = new char[len+2*cnt+1];
int p = 0;
for(int i=0; i<len; ++i)
{
if(c[i] == ' ')
{
cc[p] = '%';
cc[p+1] = '2';
cc[p+2] = '0';
p += 3;
}
else
{
cc[p] = c[i];
++p;
}
}
cc[p] = '\0';
return cc;
}
Your function passes the pointer to the allocated memory back to the calling code. It passes the ownership of this memory to the caller. Which means that the function does not leak, assuming that the calling code receives the pointer and keeps track of it (and eventually deallocates the memory).
In other words there's nothing to suspect a leak in this code. From the memory leak prevention perspective there's nothing wrong with this code.
If your program leaks this memory, it is the calling code's fault, not this function's fault.
This code doesn't leak, per se, but you leave it for the caller of replace1() to delete[] that memory, or else it will be leaked.
No, this code doesn't leak - it returns the resource. Everything is OK.
As a part of documentation for this function should be something like - returns dynamically allocated memory; caller should free the result.
If someone outside does not free the resource, then it will be leak, but in outside code, not in this function.