shared pointer of dynamically allocated int array triggered a breakpoint - c++

Thanks in advance for people who help.
I am new to C++. I am learning the concept of smart pointer/shared pointer and using Visual Studio 2013RC. Following the example in wikipedia, I created a shared pointer like this
SharedPointer.cpp
#include <iostream>
#include <memory>
//using namespace std;
void main(){
std::shared_ptr<int> sp1(new int(5), std::default_delete<int[]>());
//std::shared_ptr<int> sp2 = sp1;
for (int i = 0; i < 5; i++) sp1.get()[i]= i;
for (int i = 0; i < 5; i++) std::cout << sp1.get()[i] << std::endl;
system("pause");
}
The program compiles and prints out 0,1,2,3,4 without any error, but then it comes the window saying "SharedPointer.exe has triggered a breakpoint."
Could anyone tell me what is the reason for this exception?
Thanks a lot

You should have used int[5] instead of int(5) here:
std::shared_ptr<int> sp1(new int[5], std::default_delete<int[]>());
Currently, your code allocates a single int which is initialized to 5, and then it tries to access it as an array of five ints (undefined behavior). After that, the smart pointer tries to delete that int with a delete[] operator (instead of a "plain" delete operator) which is also an undefined behavior.

sp1 is destroyed at the end of your program, causing the default deleter to run. The default deleter here invokes delete[], but since you didn't use new[], this is invalid.
In fact, from the looks of things, you meant new int[5] rather than new int(5), because you're also attempting to access five elements of this memory block where in fact you only allocated one.

Related

How to free memory allocated in a function without returning its pointer?

I have a function like this:
int fun(){
int* arr = new int[10];
for(int i = 0; i < 10; i++){
arr[i] = 5;
}
delete[] arr; //
return arr[6];
}
int main(){
std::cout << fun();
return 0;
}
What am i going to do is to free the memory whick is pointed to by the pointer arr. But the function is not returning pointer arr. So i tryed to free it inside the function.
It won't print anything if delete[] arr is above return arr[6] (Using Visual Studio 2019).
But if return arr[6] is above delete[] arr , would the memory be freed or this sentence be skipped?
Or should i declare arr inside main() then free it in main()?
Unless it's for academic purposes, you rarely see a C++ program using manual memory allocation, you don't need to do it since you have a set of containers in the STL containers library that do this memory management reliably for you. In your particular example, a std::vector is recommended.
That said, to answer your question:
It won't print anything if delete[] arr is above return arr[6] (Using Visual Studio 2019).
If you delete the array before accessing the data stored in it the behavior is undefined. It's only natural that it doesn't print anything. It could also print the expected result, that's one of the features of undefined behavior. Using Visual Studio or not, it's the same.
But if return arr[6] is above delete[] arr, would the memory be freed or this sentence be skipped?
Yes it would be skipped, or more accurately, all code after the return statement will not be executed. The memory will not be freed.
Or should I declare arr inside main() then free it in main()?
If the data should belong in the main's scope you should definitely declare it there, you can pass it to the function as an argument:
#include <cassert>
#include <iostream>
int fun(int* arr) {
assert(arr);
for (int i = 0; i < 10; i++) {
arr[i] = 5;
}
return arr[6];
}
int main() {
int* arr = new int[10];
std::cout << fun(arr);
delete[] arr;
return 0;
}

c++ array and memory location

I have a piece of code that deals with C++ array.
using namespace std;
#include <iostream>
int main(){
int *p;
p = new int[3];
for(int i = 0; i < 3; i++){
p[i] = i;
}
//delete[] p;
for(int i = 0;i <3; i++){
std::cout << *(p+i) << std::endl;
}
}
How does this code work? How does the memory location *(p+i) work? How is it different from using p[i]. What are the differences on the code if we uncomment the line delete[] p.
1) When you do this:
p = new int[3];
Now, p points to the first element of the dynamically allocated array.
When you do, *(p + i) will lead to simple pointer arithmetic. It will boil down to: value of (<address pointed by p> + <size of type pointed by p> * i) which is equivalent to doing p[i].
That's why it works.
2) In C++, unlike java, you have to explicitly clear the dynamically allocated memory using delete, as there is no GC in C++ (and will never be, as per Bjarne Stroustrup). Otherwise, the memory area will remain acquired for the application lifetime, thereby causing memory leak.
Suggestion:
Place your delete at the end of the program. Otherwise, the loop below it may give SIGSEGV.
Also, Avoid using new and delete as much as you can.

A piece of C++ code get "invalid pointer" error

Here is the code:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
int *p = new int[2];
p[0] = 1;
p[1] = 2;
cout << *p++ << endl;
delete p;
return 0;
}
It can be compiled, but got a runtime error "free(): invalid pointer", followed by a memory map.
operating system ubuntu 10.10
compiler: g++ 4.4.3
You need to call the array-version of delete:
delete[] p;
EDIT: However, your real problem is that you're incrementing p.
The delete operators only work on the original pointers that were allocated.
Your call to delete must use the same pointer returned by your call to new.
In your code, you increment p with *p++, which due to operator precedence is interpreted as *(p++). Due to this, you are providing delete a pointer that the memory manager has never heard of.
Additionally, you should use delete[] to match a call to new[].
That being said, here is a guess of what you may have intended:
int *p = new int[2];
p[0] = 1;
p[1] = 2;
for(int i = 0; i < 2; i++)
cout << p[i] << endl;
delete[] p;
return 0;
Look a the code:
int *p1 = new int;
int *p2 = new int[2];
int *p3 = p1;
int *p1 = p2;
delete p3;
delete[] p1;
Pointers p1 and p2 have the same representation and the same set of allowed operations. For the compiler they are both int*.
Althougth the objects that they are pointing at are significantly different. The object from new int[2] at hegative offset has a header that contains the number of items in the array.
Working with array object is the same as if it were a scalar object. Only when this object is released, it is necessary to tell the compiler what sort of object is it. A simple object or an array. This is known source of bugs and confusion. Neverthless the language was defined in this way decades ago and we cannot change this.
It is also important to delete exactly the same pointer that was returned with new. This rule applies both to simple new and new[].

Initialization of c++ heap objects

I'am wondering if built-in types in objects created on heap with new will be initialized to zero? Is it mandated by the standard or is it compiler specific?
Given the following code:
#include <iostream>
using namespace std;
struct test
{
int _tab[1024];
};
int main()
{
test *p(new test);
for (int i = 0; i < 1024; i++)
{
cout << p->_tab[i] << endl;
}
delete p;
return 0;
}
When run, it prints all zeros.
You can choose whether you want default-initialisation, which leaves fundamental types (and POD types in general) uninitialised, or value-initialisation, which zero-initialises fundamental (and POD) types.
int * garbage = new int[10]; // No initialisation
int * zero = new int[10](); // Initialised to zero.
This is defined by the standard.
No, if you do something like this:
int *p = new int;
or
char *p = new char[20]; // array of 20 bytes
or
struct Point { int x; int y; };
Point *p = new Point;
then the memory pointed to by p will have indeterminate/uninitialized values.
However, if you do something like this:
std::string *pstring = new std::string();
Then you can be assured that the string will have been initialized as an empty string, but that is because of how class constructors work, not because of any guarantees about heap allocation.
It's not mandated by the standard. The memory for the primitive type members may contain any value that was last left in memory.
Some compilers I guess may choose to initialize the bytes. Many do in debug builds of code. They assign some known byte sequence to give you a hint when debugging that the memory wasn't initialized by your program code.
Using calloc will return bytes initialized to 0, but that's not standard-specific. calloc as been around since C along with malloc. However, you will pay a run-time overhead for using calloc.
The advice given previously about using the std::string is quite sound, because after all, you're using the std, and getting the benefits of class construction/destruction behaviour. In other words, the less you have to worry about, like initialization of data, the less that can go wrong.

Deleting a dynamically allocated jagged array

I have an array of pointers that point to arrays of ints.
I have made a hard coded array of ints (check 'array' below) and I want to insert it into the array of pointers (check 'bar' below), as far as I can tell, it is still an array of pointers that point to arrays of ints.
It compiles fine; no warnings.
It runs fine; and closes fine;
Until at least, I introduce the currently commented out delete statement in the destructor.
I imagine my compiler would make a better destructor at this point, but I'm interested as to what I'm doing wrong. The terminal window just throws out a gigantic memory map; and googling and searching SO didn't help much.
class foo {
public:
int **bar;
int aSize;
//CONSTRUCTOR
foo(int aSize) {
this->aSize = aSize;
bar = new int*[aSize];
for (int i=0;i<aSize;i++) {
bar[i] = new int[aSize + i];
for (int j=0;j<(aSize + i);j++) {
bar[i][j] = 0;
}
}
}
void myfunc(int *pointer) {
bar[0] = pointer;
}
~foo() {
for (int i=0;i<aSize;i++) {
//delete[] bar[i];
}
delete[] bar;
}
};
int main() {
foo *obj = new foo(5);
int array[] = {1,2,3,4};
obj->myfunc(array);
delete obj;
return 0;
};
I know I've probably done something tragic; I just don't know what it is yet.
There is a reason why I am not using STL or other templates, it is simply because I'm interested in learning this.
Maximum criticism appreciated.
The myfunc function takes in a pointer, and then sets bar[0] to that memory address. In your example code, you pass it the address of array, which is an automatic (stack) variable. The destructor then attempts to delete[] bar[0], which points to a stack variable. This is completely undefined behavior, and the reason your program is crashing. You can't delete[] a stack array. You can only delete[] an array which was allocated using new[].
Also, the myfunc function is always going to leak memory, because bar[0] points to a heap-allocated array. When you set bar to a different memory address without first delete[]ing the previous address, you are leaking memory.
The problem is calling myfunc. In that function, you are replacing a pointer (bar[0]) that your class thinks it owns. Your obj destructor will then consequently try to run delete[] on your array[] in main, which probably causes your crash and leaves your original bar[0] dangling.