Run-time error on 2D array dynamic arrays - c++

I have the following code:
int **arr = new int*[5];
for(int i = 0; i < 5; ++i)
arr[i] = new int[];
for(int i = 0; i < 5; ++i)
delete [] arr[i];
delete [] arr;
Now it compiles and runs successfully, however if I remove the array size '5' from the first line the code compiles but crashes with run-time error on the last line. I have the following questions that I have failed to find answers in Straustrup's C++ book, in the internet etc.
Why the code crashes in the specified case ? (My guess is that delete [] fails to find the array size to be deleted and crashes.)
If it is not allowed to allocate multidimensional arrays without indicating the size why such errors are not caught by compiler at compile time ?

With the [5], you're getting an array of 5 int*s.
If you remove the [5], you're saying you want a pointer to a pointer to an int. So essentially, you have new int*[1].
Then you are indexing it with numbers from 0 to 4, which is out of bounds.

Related

C++ Using the increment operator on a pointer to dynamic memory

Is it not valid to use an increment operator on a pointer to dynamic memory in C++ when assigning the values to said dynamic memory? Or am I doing something wrong here? I am unable to find anything definitive on this specific point in any of the forums in my web searches, (mostly here in stackoverflow).
This version of my function works perfectly:
int* apply_all(const int* arr1 , size_t arr1_size, const int* arr2 , size_t arr2_size)
{
int it {};
int* pArr = new int[arr1_size * arr2_size];
for(size_t i {}; i < arr1_size; ++i)
for(size_t j {}; j < arr2_size; ++j)
pArr[it++] = arr1[i]*arr2[j]; // <-- This works perfectly!
return pArr;
}
The expected result of printing out the contents of the dynamic memory pointed to by the returned pointer is:
[ 10, 20, 30, 20, 40, 60, 30, 60, 90, 40, 80, 120, 50, 100, 150 ]
But when I try the below version I get a seg fault:
int* apply_all(const int* arr1 , size_t arr1_size, const int* arr2 , size_t arr2_size)
{
int* pArr = new int[arr1_size * arr2_size];
for(size_t i {}; i < arr1_size; ++i)
for(size_t j {}; j < arr2_size; ++j)
*(pArr++) = arr1[i]*arr2[j]; // <-- This does not work!!
return pArr;
}
The above causes this output:
"[ 0, 0, 0, 1041, 0, 741351515, 539766816, 824192048, 741422128, 539766816, 858862647, 825569589, 891300917, 909588787, 909195318 ]
Segmentation fault (core dumped)
Process returned 139 (0x8B) execution time : 0.114 s"
This is from an assignment in a beginning C++ course where one of the requirements is to write a function with 2 int arrays and their sizes as the parameters. The function is to return a pointer to an array in dynamic memory (composed of values arithmetically generated using the input parameters). I am using codeblocks in linux mint with GNU GCC Compiler (c++ compiler: G++) and GDB. But I have no compiler flags for C++ selected as they were causing problems when selected and I read somewhere ( I believe it was a post on here ) to fix the problem by not selecting any flag. (Not sure if this is a factor or not.)
I have also tried *pArr++ and get the same result. Is this something with C++ or is it because of my compiler or something. I have not been studying C++ for very long and only started studying coding with C in October of last year, so there is much I still do not know that may be basic to you all. But I REALLY want to learn. Thanks in advance. If you need the entire program let me know. I just surmised it wasn't really pertinent to the question.
Whenever you increment a pointer you have to save a copy before you return it, this is also an advice for Linked List where you access each following nodes but want to save address of the very first one. So in your case:
int* apply_all(const int* arr1 , size_t arr1_size, const int* arr2 , size_t arr2_size)
{
int* pArr = new int[arr1_size * arr2_size];
Int* tmp = pArr; // you store pointer of pArr in tmp, it will not be incremented.
for(size_t i {}; i < arr1_size; ++i)
for(size_t j {}; j < arr2_size; ++j)
*(pArr++) = arr1[i]*arr2[j]; // <-- This does not work!!
return tmp; // you return tmp which point at the address of pArr where the first item is located
}

why does this c++ code run on Dev c++ but not on a website?

This code takes input of an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once. We have to return the missing numbers.
Input:
[4,3,2,7,8,2,3,1]
Output:
[5,6]
It works totally fine in Dev C++, but when i submit it a website called leetcode, it is giving me the following error
Runtime Error message:
Line 924: Char 9: runtime error: reference binding to null pointer of type 'int' (stl_vector.h) SUMMARY: UndefinedBehaviorSanitizer:
undefined-behavior
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_vector.h:933:9
vector<int> findDisappearedNumbers(vector<int>& nums)
{
vector<int> temp;
const int len = nums.size();
int j=0;
//sorted the array
sort(nums.begin(), nums.end());
//Added non-repetitive numbers into a temp vector
for(int i=0;i<len;i++)
{
if(nums[i]!=nums[i+1])
{
temp[j++]=nums[i];
}
}
//cleared nums vector for later use
nums.erase(nums.begin(), nums.end());
//added missing numbers in the sequence to both temp and nums vectors
for(int i=0;i<len;i++)
{
if(temp[i]!=i+1)
{
temp.insert(temp.begin()+i, i+1);
nums.insert(nums.end(),i+1);
}
}
return nums;
}
I know this code is inefficient, i have just started with c++, but can someone tell why it doesnt work on the site?
Your vector temp is empty when you do this:
temp[j++]=nums[i];
So you are accessing elements out of bounds. That's undefined behaviour and you cannot have any expectations on the result. Anything could happen. The compiler has no obligations any more once your code contains UB.
It only appears to work fine in Dev C++. As the error message of the other compiler says, you have Undefined Behaviors in your code. Jesper has pointer one.
Another one would be the line:
if(nums[i]!=nums[i+1])
During the last iteration i is equal to len-1, so nums[i+1] tries to read num[len] which does not exist.
You would need to change the loop to:
for(int i=0;i<len-1;i++)
The second loop is a little harder to fix. You are using len as limit but it is an old length of nums and you are iterating over temp. Additionally, you are modifying temp during that. What you need to do, is to check size of temp after every iteration and compare i to the current number:
for(int i=0;i<temp.size();i++)
As a side note. There are functions to clear a vector / add an element at the end. You can find the full list here.

Memory allocation with unknown number of elements

Since the number of elements is determined by some conditions, I wrote a program like this;
int i = 0;
int *layer;
while (i != 12){
layer = new int;
layer[i] = i;
cout << layer[i] << endl;
i++;
}
delete[] layer;
return 0;
I get the result;
0
1
2
3
4
5
6
And then program crashes. What is the reason of this and how should I modify the program in order to allocate memory for unknown number of elements?
Thanks in advance!
You have undefined behaviour. You allocate space for a single int, then you treat it as an array.
layer = new int; // single int
layer[i] = i; // wat??
Then you leak the memory, then you call delete[] on the last newed int. Since it isn't clear what you want to do with your code, I can only offer some suggestions:
Consider using std::vector<int> as a dynamic array. It will save you a lot of trouble.
If you must allocate an array with new (you probably don't), you need new int[n] where n is the number of elements.
Call delete [] for every new[] and delete for every new.

initializing a multi dimensional array c++

I am working in VC++ 2008, and am trying to allocate a multi-dimensional array of chars to do some file work. I know that whenever an array is allocated all the members of the array should be initialized usually in a successive order. what I have currently is this.
char ** thing = new char *[lineY];
for (int ii = 0; ii < lineY; ii++){
thing[ii] = new char[lineX];
}
... // working with array
// deleting each part of the array.
for (int ii = 0; ii < lineY; ii++){
delete [] thing[ii];
}
delete [] thing;
the problem that I am running into is that if I add the array to the watch list, or put a break right after its been allocated the debugger states that the array is equal to a number like 51, or 32, and not a block of space with indexes, and values, but when I try to initialize the values of each index by making my allocation this:
char ** thing = new char *[lineY];
for (int ii = 0; ii < lineY; ii++){
thing[ii] = new char[lineX];
for (int jj = 0; jj < lineX; jj++){
thing[ii][jj] = '';
}
}
edit: the compiler throws "C2137 empty character constant" am I doing something wrong?
edit: read msdn on the error number, and found answer
You cannot write thing[ii][jj] = '' because '' is an empty character constant which isn't allowed. Try replacing '' with something like ' ' (with the space between 's)
Are lineX and lineY compile-time constants? In that case:
std::array<std::array<char, lineX>, lineY> thing;
Otherwise:
std::vector<std::vector<char> > thing(lineY, std::vector<char>(lineX));

Stack push causes critical error

I am new to C++ and working with STL container at the moment.
I got a serious problem executing a nodeStack.push(startnode) - the compiler shows up a
Critical error detected c0000374
Followign code shows the function where the mentioned error occurs:
vector<int> Graph::iterativeDepthSearch(map<int, vector<int>> adjlist, int startnode) {
stack<int> nodeStack;
vector<int> visitList;
// Knotenbesuchsliste initialisieren
int* val = new int(adjlist.size());
for (int i = 0; i < (int) adjlist.size(); i++) {
val[i] = 0;
}
int cnt = 1;
nodeStack.push(startnode);
....
}
The error occurs in the line nodeStack.push(startnode);, startnode is initialized with 0.
try int* val = new int[adjlist.size()]; you are currently allocating a single int and initializing its value, not allocating an array of ints.
The stack structure is corrupting because it is next to your pointer in the memory stack.
nodeStack.push isn't really your problem. You are declaring int* val - a pointer to int, then initializing the integer at val with the size of the list. You really want
int *val = new int[adjlist.size()];
It's possible that you are using an x86 DLL; when I got this error in VS4.5, I changed my target platform to x86 and switched to .Net 4.0. That worked for me.