Program crashes (Dynamic memory allocation) - c++

I just started reading about dynamic memory allocation and for some reason my program crashes.
void getSpace(int *ptr)
{
ptr = new int [100];
}
void getData(int *ptr)
{
cin >> *(ptr);
cin >>*(ptr+1);
}
int main()
{
int *ptr = NULL;
getSpace(ptr);
getData(ptr);
}
But for some reason, this one doesn't. It seems like if I declare the pointer at the same function as where I get the array into the heap size I wanted, it doesn't crashes.

int* ptr is local copy of pointer, so you only allocate the memory inside scope of getSpace, and you assign it into ptr variable, but it is local to the getScope, and so the main function does not see the allocation. You should either do int** ptr and do *ptr = new int[100]; or int*& ptr and then ptr = new int[100];

Change to:
void getSpace(int **ptr)
{
*ptr = new int [100];
}
and call it:
getSpace(&ptr);

Related

return pointer with new operator. Where to put delete?

Im fairly new to C++.
So I learned that new allocates memory and returns a pointer of my datatype. But can I use this in a function and return the pointer? If so then where should I place the delete operator?
Is the following code legal?
int *makeArray(int size)
{
int *result = new int[size];
delete[] result;
return result;
}
int main()
{
int *pointer = makeArray(10);
/* code ... */
return 0;
}
It is compiling and working but logically it makes no sense because I deleted my array.
So I tried the following:
int *makeArray(int size)
{
int *result = new int[size];
return result;
}
int main()
{
int *pointer = makeArray(10);
/* code ... do some stuff with pointer */
delete[] pointer;
return 0;
}
Is this safe or does it cause a memory leak? Is there a better way of returning the pointer?
I tried both versions and they are compiling and working but I'm sure at least one of them if not both are unsafe.
Is the following code legal?
int *makeArray(int size)
{
int *result = new int[size];
delete[] result;
return result;
}
int main()
{
int *pointer = makeArray(10);
/* code ... */
return 0;
}
Definitely not! This is Undefined behavior because you return a deleted pointer. After using the delete operator you're telling your OS that it can release the memory and use it for whatever it wants. Reading or writing to it is very dangerous (Program crashing, Bluescreen, Destruction of the milky way)
int *makeArray(int size)
{
int *result = new int[size];
return result;
}
int main()
{
int *pointer = makeArray(10);
/* code ... do some stuff with pointer */
delete[] pointer;
return 0;
}
Is this safe or does it cause a memory leak?
Yes this is the correct way of using the new and delete operator. You use new so your data stays in memory even if it gets out of scope. Anyway it's not the safest code because for every new there has to be a delete or delete[] you can not mix them.
Is there a better way of returning the pointer?
YES. It's called Smart Pointer. In C++ programmers shouldn't use new but smart pointer at all. There is a C++ community Coding Guideline to avoid these calls Guideline R11

Function with pointer as parameter - what does the function expect by calling?

I saw this example:
void pass_by_value(int* p)
{
//Allocate memory for int and store the address in p
p = new int;
}
void pass_by_reference(int*& p)
{
p = new int;
}
int main()
{
int* p1 = NULL;
int* p2 = NULL;
pass_by_value(p1); //p1 will still be NULL after this call
pass_by_reference(p2); //p2 's value is changed to point to the newly allocate memory
return 0;
}
if i call the function pass-by-value, shouldnt it expect something like "&p" instead of p?
The pass-by-value is messed up anyway, the value passed to the function would be lost when the call completes and the memory would leak. It's legal code, it's just useless. If not using references or function return value the function would need to take a pointer-to-pointer (really, the compiler is likely to produce the same code for both the pointer-to-pointer and reference-to-pointer cases - barring inlining - it's just a bit cleaner to use the reference):
void foo(int ** p)
{
*p = new int;
}
int main()
{
int * p = nullptr;
foo(&p);
delete p;
}

Program crashes whenever i run the commented code

Whenever i run the commented part of the constructor money the program crashes.
When i compile it, it does not throw any error as well.
Can someone tell me what is happening?
Also i am trying to implement the vending machine problem here.
i have removed some parts of the code which are working properly.
#include <iostream>
using namespace std;
class money
{
public :
int *max;
int *accepted_values = new int[10];
bool present;
int *deposited;
int i;
money()
{
}
money(int *a, int how_many)
{
//*max = how_many;
// for (i=0; i<how_many; i++)
// {
// accepted_values[i] = a[i];
// }
//*deposited = 0;
present = false;
}
};
class Vending_machine
{
public :
money *coins = new money(accepted_coins, 5);
//money *coins = new money();
int *amount_deposited = new int;
Vending_machine()
{
cout<<"Cool";
}
~Vending_machine()
{
delete amount_deposited;
}
};
int main()
{
Vending_machine a;
}
You are dereferencing the int pointers int *max and int *depositedin your constructor, without assigning a proper memory address first.
This will always crash, since it's undefined behaviour.
int* myPointer;
*myPointer = 10; // crashes
A pointer has always to point to a valid address first, before you can use it.
This could be the address of another variable:
int myInt;
int *myPointer = &myInt;
*myPointer = 10; // doesn't crash - myInt now is 10.
or it could be dynamically allocated and released.
int* myPointer = new int;
But in that case you'll have to take care that the memory is released once you are done.
delete myPointer;
A better solution is to use std::unique_ptr<>, which takes care of releasing its pointer on destruction.
But the best solution is not to use pointers at all, if they are not really necessary - especially if you don't know very exactly how pointers work. I assume in your example you could avoid pointers completely.

I want to make an array of structure dynamically but I get a heap corruption error:

Hello stackoverflow
so my question is: I want to make a function to generate the array of structures but i get an error whenever i finish inserting the values what is the problem?
like so
struct INFO
{
char name[20]; // creating the strucure
int age;
};
void generateArr(INFO *p); // a function to generate the array
void readArr(INFO *p); // a function to read the array
int main()
{
INFO *ptr =new INFO; // a pointer that points to the structure
generateArr(ptr); // calling the functions
readArr(ptr);
delete[]ptr; // deallocating memory
}
void generateArr(INFO *p)
{
p = new INFO [3]; // generating three INFO structures
}
void readArr(INFO *p)
{
for (int i = 0; i < 3; i++)
{
cin >> p[i].name>> p[i].age; // inputting the elements
cout << endl;
}
}
I tried to make the code as clear as possible, ask me if anything is ambiguous.
This function :
void generateArr(INFO *p)
{
p = new INFO [3]; // generating three INFO structures
}
is not working as you expect it does. It assigns allocated memory to local 'p` parameter, which is not returned to a main. To fix it change p to reference:
void generateArr(INFO *&p)
[edit]
but since you already assigned ptr in main with INFO *ptr =new INFO;, you will get a memory leak this way. So you should remove that line.
In generateArr(INFO *p), you allocate an array which address is stored in local variable p; on return from the function, any local variable (such as p) is lost, as long as address of the allocated array.
You should get rid of function generateArr(INFO *p), which is useless, and allocate your array into main(), this way :
int main()
{
INFO *ptr =new INFO[3];
readArr(ptr);
delete[]ptr; // deallocating memory
}
Rewrite the functions at least the following way
INFO * generateArr( size_t n )
{
return new INFO [n]; // generating three INFO structures
}
void readArr(INFO *p, size_t n )
{
for (int i = 0; i < n; i++)
{
cin >> p[i].name>> p[i].age; // inputting the elements
cout << endl;
}
}
and in main call them like
const size_t N = 3;
INFO *ptr = generateArr( N ); // a pointer that points to the structure
readArr( ptr, N );
delete []ptr; // deallocating memory
As for your code then in this statement
INFO *ptr =new INFO; // a pointer that points to the structure
there is allocated only one object of the structure type however it is deleted using operator delete [] instead of the operator delete.
delete[]ptr; // deallocating memory
And inside this function
void generateArr(INFO *p)
{
p = new INFO [3]; // generating three INFO structures
}
there is a memory leak because variable p is a local variable of the function that was initialized by the value of the function's argument and that will be destroyed after exiting the function. As result the address of the dynamically allocated memory will be lost.

C++ check if pointer is valid?

I'm having problems with valid pointers in C++. I'm using one object in different threads, so I can't just set the pointer to NULL and return. Here's what I'm trying:
int main()
{
char *ptr = new char[1024]; //assume PTR = 0x12345678
changePtr(ptr); //after calling this,
//ptr is not NULL here.
return 0;
}
void changePtr(char *ptr)
{
delete [] ptr; //ptr = 0x12345678
ptr = NULL; //ptr = NULL
}
How can I change ptr to NULL for both functions?
change the signature of changePtr to:
void changePtr(char **ptr)
{
delete [] *ptr; //ptr = 0x12345678
*ptr = NULL; //ptr = NULL
}
And call it using:
changePtr(&ptr);
In C++, use reference parameter:
void changePtr(char *&ptr) {
delete [] ptr; //ptr = 0x12345678
ptr = NULL; //ptr = NULL
}
In C, you need to pass pointer to pointer, which is basically same thing with less pretty syntax.
You do not need to change the calling code. But you must give a modifiable variable as argument when calling, can't give for example NULL or nullptr, same as you can't do &NULL.
If you really want to manage memory in such a complex, error-prone way, then pass a reference to, rather than a copy of, the caller's pointer:
void changePtr(char *&ptr)
// ^
Much better would be to use a smart pointer; they are designed so that it's very difficult to leave them dangling when the target is deleted:
int main()
{
std::unique_ptr<char[]> ptr(new char[1024]); //assume PTR = 0x12345678
changePtr(ptr); //after calling this,
//ptr is empty here.
return 0;
}
void changePtr(std::unique_ptr<char[]> & ptr)
{
ptr.reset();
}
although if I wanted a dynamic array, I'd avoid new altogether and use std::vector.
I have seen a great many questions about how to check a pointer for validity. A large number of these questions have been about Windows. There may not be a general way to check in C++, but for a Windows specific solution the following seems to work on my system:
#include <windows.h>
#include <stdio.h>
int main(int argc, char **argv)
{
MEMORY_BASIC_INFORMATION lpBuffer;
int cActualBytes;
cActualBytes = VirtualQuery(&main, &lpBuffer, sizeof(lpBuffer)); // Can we get info about main?
if (!cActualBytes)
{
printf("Nope, you can't do that \n");
return 2;
}
if (cActualBytes != sizeof(lpBuffer))
{
printf("Surprise! Expected %d bytes, got %d\n", sizeof(lpBuffer), cActualBytes);
}
printf("Information for main\n");
printf("---------------------------\n");
printf("C reports pointer %p, Virtual Alloc sees it as %p\n",&main,lpBuffer.BaseAddress);
return 0;
}