how to free malloc outside of function - c++

Can't resolve this problem - my compiler allways tells me that I have some troubles with the free(pointer) function. So I'm not sure about the working of my pointers but debugging has shown that actually everything works well. Only the free function could't free the memory.
#include <stdio.h> //Bibliothek für input/output.
#include <stdlib.h> //For malloc
#include <math.h> //Bibliothek für matchematische Operationen.
#include <iostream> //Bibliothek für in/output in C++.
#include <stdbool.h> //Bibliothek für boolean
//Prototypes
int* readNumbers(int size);
int sumUpNumbers(int* sumpointer, int size);
//Main function
int main()
{
int arraySize; //Size of the malloc-array
int* pointer; //pointer for storing of the malloc-address
int total; //variable for the sumUpNumbers function
pointer = NULL; //point on zero
//inform the user before getting a number from him
std::cout << "Please give the size of array:" << std::endl;
fflush(stdout); //free the output window
//get a number for the size of array
scanf("%d", &arraySize);
//call the readNumbers function and store the first address of
//the malloc-array in pointer
pointer = readNumbers(arraySize);
//call the sumUpNumbers function and store the number in total
total = sumUpNumbers(pointer, arraySize);
fflush(stdout); //free the output window
//show the number from total
printf("\n total of the array:%d", total);
//call the free function for making the memory of
//the malloc-array free again
free(pointer);
fflush(stdin); //free the keyboard buffer
getchar(); //wait for a feedback from user
return 0; //return 0 to the machine in case if everything works well
}
//This function has a pointer extension because we want to work with the
//array outside of this function. We give the function a size of the array
//we want to build. The function builds an array and fills it with numbers
//and than gives us back the first address of the array.
int* readNumbers(int size)
{
int* array; //pointer for creating of malloc-array
int i; //counter
//pointer for storing of the first address of the array
int* helpPointer;
array = NULL; //set the pointers
helpPointer = NULL; // on zero
//create the array
array = (int *) malloc(size * sizeof(int));
//check the value of the array to be sure that we have created
//the array without errors
if(array != NULL)
{
//store the first address of the malloc-pointer
helpPointer = array;
//give some value to all the parts of array
for(i=0; i<=size; i++)
{
//inform the user
printf("\n give the %d. nummber of the array:\n", i+1);
fflush(stdout); //free the output window
//read the value
scanf("%d", array+i);
}
return helpPointer; //return the first address
}
//if something went wrong by creating of the array, do:
else
{
//tell the user, what we computer does't have enough memory
std::cout << "There is no place for saving the data in mamory";
return 0; //return with failure
}
}
//The input of this function is a pointer with the address of the malloc-array
//from the readNumbers and the size of this array. The function adds all the numbers
//from the array and gives us the result of the additation back.
int sumUpNumbers(int* sumpointer, int size)
{
int sum; //variable for storing of total value
int i; //counter
sum = 0; //set the sum on zero before work with it
//count all the values from the array
for(i=0; i<=size; i++)
{
//count one number after another
sum = sum + *(sumpointer+i);
}
return sum; //return the total value
}

The limits of your for loops are wrong. You are writing into one position over the end of your array, which might corrupt the memory so that later the program fails. Change the for loops to:
for(i=0; i<size; i++)

In the readNumbers function you have:
for(i=0; i<=size; i++)
but the array is only size elements long, so just change <= to <:
for(i=0; i < size; i++)
You have the same problem in the sumUpNumbers function. But this will most likely just result in an incorrect sum although it is technically undefined behaviour.

Your code has few issues:
fflush(stdin) is a generator of undefined behavior.
two incorrect counters: if size is size, you must count for(i = 0; i < size; i++)
Your int* readNumbers(int size) returns int instead of int* if array is NULL.
strange mixing of C and C++ for no obvious reason to using cin and cout
Apart from having written three obvious mistakes (1) and (2) and (3), you also push yourself to use a C++ compiler (4) for compiling something, 99% of which is plain C code. Why?
In case you replace cin and cout with appropriate scanf() and printf() calls, you get rid of C++. So you can use a C compiler. In that case make sure to also modify malloc call in order to conform the C standard:
array = malloc(size * sizeof(int)); //no result casting!
Then you get 100% C code which is easier to read, study and debug.

Related

C++ 2D Array Allocating Memory to Avoid Segmentation Fault

I usually code in other languages (R, Python and Java), but recently started using C++. I've been solving problems on hackerrank.com, and specifically I bumped into this one:
https://www.hackerrank.com/challenges/variable-sized-arrays
Prior to this question, I had never gotten a Segmentation Fault error. I've tinkered with the code and discovered that the error only occurs when I attempt to print from the arr variable.
I wonder if someone could help me with this, and maybe provide a detailed explanation as to the precise error?
The code is as follows, but the issue is likely with int arr[100000][100000] = {-1}; and printf("%d\n", arr[iHat][jHat]); because I can printf both iHat and jHat themselves, but I am unable to use them to access integers in the arr array.
#include <iostream>
using namespace std;
int main(){
int n, q;
/*
*scan in:
*n array entries
*q quaries
*/
int arr[100000][100000] = {-1}; //initialize an array, larger than 10^5
scanf("%d %d\n", &n, &q); //n is size of array, q is # of quaries
for (int i = 0; i < n; ++i){ //loop through lines of input to populate array
int c, y = 0; //initialize to zero at the start of each line
while((c = getchar()) != '\n'){ //readline
if(c != ' '){ //pass spaces
arr[i][y] = c; //place integer into array
++y;
}
}
}
for (int i = 0; i < q; ++i){
int iHat, jHat = 0;
scanf("%d %d\n", &iHat, &jHat); //scan for coordinates
printf("%d\n", arr[iHat][jHat]); //Segmentation fault occurs here, why?
}
return 0;
}
Update
This question focused on memory management, and in particular the use of pointers. A functioning solution, resulting in no segmentation faults, is as follows:
#include <iostream>
using namespace std;
int main(){
int n, q;
/*
*scan in:
*n array entries
*q quaries
* format: %d %d
*/
scanf("%d %d\n", &n, &q);//n is size of array of arrays, q is # of quaries
int **arr = new int *[n]; //int** arr is a pointer of pointers of size n
for (int i = 0; i < n; ++i){//loop through lines of input to populate array
int k; //Always initialize variables in the narrowest scope possible!
scanf("%d", &k);//grab k, the number of ints in the line
arr[i] = new int[k];//create a 2nd dimension at entry i of size k
for (int j = 0; j < k; ++j){
scanf("%d", &arr[i][j]);//populate array
}
}
for (int i = 0; i < q; ++i){
int iHat, jHat = 0;
scanf("%d %d\n", &iHat, &jHat); //scan for query coordinates
printf("%d\n", arr[iHat][jHat]); //print results of query
}
return 0;
}
C++ gives you control of where you want to allocate memory. In your case, what you have found is that you allocated an array-of-array-of-int on the stack which exceeds the stack size. At some point, you access one of these elements which lies outside the bounds of the stack and also the program, which causes an access violation called a segmentation fault.
Since you mentioned being new to C++, it would help to understand these 3 areas of memory and how you would use each for your case:
Stack memory - space for temporary variables to automatically use without having to explicitly request. You will see undefined behavior if you exceed the stack size.
int main() {
int arr[100000][100000];
}
Heap memory - space for dynamically allocating space whenever explicitly requested using the operator "new". An "std::bad_alloc" exception will be thrown if the requested memory size exceeds what is available.
int main() {
int **arr = new int *[100000];
for (std::size_t i = 0; i < 100000; ++i) {
arr[i] = new int[100000];
}
}
Static memory - space allocated for static objects before main runs. You will get a compiler error if the array dimensions are too large.
int arr[100000][100000];
int main() {
...
}
That's 40 GB!
Even if you have that much RAM in the machine, it is surely not allocated as stack space.
If you do have that much memory you can move the arr to the global area before main. That way it will not be on the stack.
If you don't have 40+ GB available, you might have to rethink the solution. :-) Perhaps do the calculations in smaller segments?
Here are a few thoughts
1) You are trying to allocate 100,000 x 100,000 bytes, which equal 10,000,000,000 bytes (~10GB) on the stack. The default stack size is about 8MB on 32-bit linux. Even if the stack size is larger it won't be 10GB.
2) The name of the exercise you were working on is "Variable Sized Array" The line you entered,int arr[100000][100000] is a fixed size array. You should be using keyword new to dynamically create the array.
3) The reason for the Segmentation Fault error is because your print statement is attempting to access memory outside of the Virtual Memory space allowed for a stack size.
[Suggestion]
1) trying doing some exercises where you allocate and clean up dynamic memory using new and delete. Also in C++ allocating and deleting arrays is done differently than just a single data structure.
Cheers
Are you trying to do this?
#include <iostream>
using namespace std;
int main(){
int n, q;
const int length = 100;
int arr[length][length] = { -1 };
cout << "Enter length of 2d array" << endl;
cin>>n>>q;
cout << "Fill the array" << endl;
for (int i = 0; i < n; ++i) {
for(int y=0;y<q;y++){
int f;
cin >> f;
arr[i][y]=f;
}
}
int iHat;
int jHat;
cout << "Enter coordinates" << endl;
cin>>iHat>>jHat;
cout<<arr[iHat][jHat];
return 0;
}
P.S i decreased array size, becouse 100000 x 100000 this is lot of gigabytes and it says array is too large

linker error in C++ (again) [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 7 years ago.
so I needing some help with creating a program for my class. The lab requires us to use pointers.
This is the description of what we have to do...
-Write a function that accepts an int array and the array's size as arguments.
-The program should ask the size of the array and lets the users enter some integer values.
-The function should create a new array that is one element larger than the argument array.
-The first element of the array should be set to 0.
-Element 0 of the argument array should be copied to element 1 of the new array.
-Element 1 of the argument array should be copied to element 2 of the new array, etc.
-The function should return a pointer to the new array.
-There should be three other functions: getMode, getMedian and getAverage.
-These functions should get Mode, Median and Average of the values within an array.
-You should display the argument array and the new array as well as the mode, median and the average.
This is what I have so far I'm not sure if its right. Any help is greatly appreciated.
UPDATE: I run the program and it asks the user for the size of the array and the values for it...
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <string>
int* addToSize (int*, int);
using namespace std;
int main()
{
int userSize=0; //Holds user size
int userInts; //Holds uaer values
int *memory; //dynamically allocate an array
//int *intptr;
//int *arrayNew;
//int newA;
//Gets array size
cout << "Please enter the array size!" << endl;
cin >> userSize;
//Memory array
memory = new int [userSize];
//Grab values for the amount of user size
for (int count = 0; count < userSize; count ++)
{
cout << "Please enter the value for " << count+1 << endl;
cin >> userInts;
}
for (int index = 0; index < userSize; index ++)
{
cin >> memory[index];
}
//Sets addToSize function to memory array
memory = addToSize(memory, userSize);
//Shows memory array
for(int index=0;index< (userSize + 1);index++)
cout<<memory[index]<<endl;
delete[] memory; //Used to delete memory array
memory = 0; //sets memory array to 0
return 0;
}
int* addToSize(int* arrayNew, int newSize)
{
int* expandSize= new int [newSize +1];
for (int index = 0; index < newSize; index++)
{
expandSize[index]= arrayNew[index];
}
for (int index = newSize; index < (newSize+1); index ++)
{
expandSize[index]=0;
}
return expandSize;
}
You have declared a forward reference to some addToSize() function which accepts 2 arguments, and you proceed to invoke it from within your main(), and that's all very fine and dandy, but then further down you define an addToSize() which accepts 3 arguments.
So, what is happening is that the declared function is unrelated to the defined function. The compiler completely ignores the 3-argument function, since you are not calling it, and it assumes that you will provide a definition for the two-parameter function in some other source file.
But then when the linker attempts to link your program, there is no other file containing an addToSize() with two arguments, so the linker fails with an error message which describes precisely what happened. (It is a linker error. It has nothing to do with pointers and arrays.)
Hint: before fixing your function definition to match the declaration, lose the forward declaration, move the function to the start of the file, and make it static.

After passing by reference to modify an array, why it stays the same?

I am practicing pointers by creating a Big Number struct, which has numDigits (number of digits) and digits (contents of the big number).
I create a function called removeZero(). After passing the integer array and the size n into it, because of passing by reference, I am supposed to cut down the leading zeros for my input. It works, when the integer array is in main function. However, when I pass an array that is in readDigits, it does not return with a non-leading-zero version. Why? How to fix it?
struct BigNum{
int numDigits;
int *digits; //the content of the big num
};
int main(){
int A[] = {0,0,0,0,0,0,1,2,3};
int n=9;
int *B=A;
//removeZero(A,n); If I use this, it cannot compile
//error: invalid initialization of non-const reference of type ‘int*&’ from an rvalue of type ‘int*’
removeZero(B,n);
for (int i=0; i<n; i++){
std::cout << *(B+i) << std::endl;
}
BigNum *num = readDigits();
return 0;
}
BigNum* readDigits(){
std::string digits;
std::cout << "Input a big number:" << std::endl;
std::cin >> digits;
//resultPt in heap or in stack?
int *resultPt = new int[digits.length()]; //in heap
int n = digits.length();
toInt(digits,resultPt);
removeZero(resultPt,n);
//Output the leading zeros, why?
for (int i=0; i<n; i++){
std::cout << *(resultPt +i) << std::endl;
}
BigNum *numPtr = new BigNum();
numPtr->numDigits = n;
numPtr->digits = resultPt;
return numPtr;
}
void toInt(std::string& str, int *result){
for (int i=0;i<str.length() ;i++ ){
result[str.length()-i-1] = (int)(str[i]-'0');
}
}
void removeZero(int* &A,int& n){
int i=0;
while (A[i]==0){
i++;
}
A=A+i; //memory leak?
n=n-i;
}
bool areDigits(std::string num){
for(int i=0;i<num.length();i++){
if(num[i]<'0' || num[i] >'9'){
return false;
}
}
return true;
}
Note that an array and a pointer are two different things. When you pass an array to a function, it degrades to a const pointer. This means that you cannot pass an array to a function which expects a int*&.
It could be the problem of scope of numPtr.numPtr is local variable of function readDigits(). Instead of returning pointer. Pass num to readDigits().
The signature of your removeZero function is:
void removeZero(int* &A,int& n);
That means the forst parameter is a reference of a pointer but the pointer is a non-const one, and you cannot therefore pass an array there, as array is a constant pointer (starting address cannot be changed).
In fact you are changing the starting address within removeZero.
With removeZero, the while loop shopuld be changed from:
while (A[i]==0){
to:
while ((A[i]==0) && (i<n)){
You have a logic error in toInt.
void toInt(std::string& str, int *result){
for (int i=0;i<str.length() ;i++ ){
// This stores the digits in the reverse order.
result[str.length()-i-1] = (int)(str[i]-'0');
}
}
That line should be
result[i] = (int)(str[i]-'0');
If you intend to keep the digits in reverse order, then removeZero has to be changed keeping that in mind.
`
When you say
int *B=A;
you are just creating a pointer to point to the same memory
of the Array A. Just by incrementing the pointer(*B) within the function
removeZero
A=A+i;
you are not deleting anything but you are just incrementing the pointer(*B)
to point to subsequent memory location within the array.
The original array memory pointed to by A remains the same, since you
have not changed any contents of the array, but you have just
incremented a pointer pointing to the same memory location as that of the array.
Also there are so many problems, like "Debasish Jana" mentioned,
you have to change your while loop. ""Code-Apprentice" gave you the reason for your
compilation error when you uncomment your commented code.
Also within "removeZero" you are incrementing A by i instead of "1" like
A=A+1;
This is one of the reason for the strange behavior you experience
Even after changing all this, you cannot see your array getting changed,
since you are not modifying any of the contents of your array.
If you really want to delete the contents of the array and change it dynamically,
you have to go for Vector<>. With static memory allocation you cannot cut the
array size short by removing some elements here and there. Learn Vector<>!

Unitialized local variable and help correcting

I am learning about pointers and the new operator in class.
In my readArray function I am to read in a size. Use the size to dynamically create an integer array. Then assign the array to a pointer, fill it, and return the size and array.
I believe I've gotten that part corrected and fixed but when I try to sort the array, i get the error "uninitialized local variable temp used."
The problem is though I get that error when I am trying to intialize it.
Any help appreciated thank you. Seeing my errors is very helpful for me.
#include <iostream>
using namespace std;
int* readArray(int&);
void sortArray(int *, const int * );
int main ()
{
int size = 0;
int *arrPTR = readArray(size);
const int *sizePTR = &size;
sortArray(arrPTR, sizePTR);
cout<<arrPTR[1]<<arrPTR[2]<<arrPTR[3]<<arrPTR[4];
system("pause");
return 0;
}
int* readArray(int &size)
{
cout<<"Enter a number for size of array.\n";
cin>>size;
int *arrPTR = new int[size];
for(int count = 0; count < (size-1); count++)
{
cout<<"Enter positive numbers to completely fill the array.\n";
cin>>*(arrPTR+count);
}
return arrPTR;
}
void sortArray(int *arrPTR, const int *sizePTR)
{
int *temp;
bool *swap;
do
{
swap = false;
for(int count = 0; count < (*sizePTR - 1); count++)
{
if(arrPTR[count] > arrPTR[count+1])
{
*temp = arrPTR[count];
arrPTR[count] = arrPTR[count+1];
arrPTR[count+1] = *temp;
*swap = true;
}
}
}while (swap);
}
You make temp an int pointer (uninitiialized), and then set the thing it points at (anything/nothing) to arrPTR[ccount]. Since you are using temp only to swap, it should be the same type as those being swapped, in this case: an int.
If it absolutely must be a pointer (there is no good reason for this, it's slow, confusing, adds potential for errors, and adds potential for memory leaks):
int *temp = new int; //make an int for the pointer to point at
bool *swap = new bool; //make an bool for the pointer to point at
do
{
//your code
}while (swap);
delete temp;
delete swap;
You declared temp as a pointer. You need to allocate it on the heap before dereferencing and assigning to it later. However perhaps a variable on the stack would be preferable?
FYI: You should be aware of the memory leak in readArray as well which is leaving callers responsible for calling delete []
Edit: I hope this will help clear up some of the other problems.
#include <iostream>
int* readArray(int&);
void sortArray(int*, int);
int main ()
{
int size(0); // use stack when possible
int *arrPTR = readArray(size);
sortArray(arrPTR, size);
// arrays are zero based index so loop from 0 to size
for (int index(0); index < size; ++index)
std::cout << arrPTR[index];
delete [] arrPTR; // remember to delete array or we have a memory leak!
// note: because we did new[] for an array we match it with delete[]
// if we just did new we would match it with delete
system("pause");
return 0;
}
int* readArray(int& size)
{
std::cout << "Enter a number for size of array.\n";
std::cin >> size;
int *arrPTR = new int[size]; // all news must be deleted!
// prefer pre-increment to post-increment where you can
for(int count(0); count < size; ++count)
{
std::cout << "Enter positive numbers to completely fill the array.\n";
std::cin >> arrPTR[count];
}
return arrPTR;
}
// passing size by value is fine (it may be smaller than pointer on some architectures)
void sortArray(int *arrPTR, int size)
{
// you may want to check if size >= 2 for sanity
// we do the two loops to avoid going out of bounds of array on last iteration
for(int i(0); i < size-1; ++i) // the first to compare (all except last)
{
for(int j(i+1); j < size; ++j) // the second to compare (all except first)
{
// do comparison
if (arrPTR[i] > arrPTR[j]) // from smallest to biggest (use < to go from biggest to smallest)
{
// swap if needed
int temp(arrPTR[i]); // put this on stack
arrPTR[i] = arrPTR[j];
arrPTR[j] = temp;
}
}
}
}
temp is a "pointer to int, which you're not initializing. When you say *temp = ... you're actually assigning to whatever temp happens to be pointing, but since you haven't told it what to point to, it can write pretty much anywhere in the address space of your program.
Because of the way you're using them, it seems that temp and swap shouldn't be pointers at all, just a plain int and bool.
You didn't initialize the temp pointer do when you dereference it you are writing to a random part of memory. Temp doesn't need to be a pointer, it can just be an int. Just replace EVERY instance of *temp with temp.

How do I return a dynamically allocated pointer array from a function?

I am now starting Dynamic Memory Allocation in class and have a ok understanding of it but can't completely use it properly. I feel like I may not be so great with pointers either :p
My instructor gave instructions to create a function named readArray that will prompt the user for a number to use as a size to dynamically create a integer array of that size. I am then to assign the new array to a pointer. I then am supposed to prompt the user to fill the array. I then am supposed to return both the newly created array and the size.
I can not figure out how to return the array though, and I thought when dynamically allocating memory you were supposed to delete the allocation after using it to prevent leaks.
The array and size must be returned to main so I can pass it to other functions such as a sorting function.
I would greatly appreciate any help I can get as my thought process with this keeps going in the wrong direction.
#include <iostream>
using namespace std;
int* readArray(int&);
void sortArray(int *, const int * );
int main ()
{
int size = 0;
int *arrPTR = readArray(size);
const int *sizePTR = &size;
sortArray(arrPTR, sizePTR);
cout<<arrPTR[1]<<arrPTR[2]<<arrPTR[3]<<arrPTR[4];
system("pause");
return 0;
}
int* readArray(int &size)
{
cout<<"Enter a number for size of array.\n";
cin>>size;
arrPTR = new int[size];
for(int count = 0; count < (size-1); count++)
{
cout<<"Enter positive numbers to completely fill the array.\n";
cin>>*(arrPTR+count);
}
return arrPTR;
}
You would not need to do that if you use std::vector<int> which is far superior choice.
Use it:
std::vector<int> readArray()
{
int size = 0;
cout<<"Enter a number for size of array.\n";
cin >> size;
std::vector<int> v(size);
cout<<"Enter "<< size <<" positive numbers to completely fill the array : ";
for(int i = 0; i < size; i++)
{
cin>> v[i];
}
return v;
}
To return an array: declare readArray() as int* readArray() [return an int* instead of an int], and return arrPTR instead of size. This way, you return the dynamically allocated array which arrPTR points to.
Regarding the delete: When you are done using the array, you should indeed delete it. In your example, do it before return 0 in your main() function.
Make sure that since you allocated memory with new[], you should also free it with delete[], otherwise - your program will have a memory leak.
Like amit says, you should probably return the array instead of size. But since you still need the size, change readArray like so:
///return array (must be deleted after)
///and pass size by reference so it can be changed by the function
int* readArray(int &size);
and call it like this:
int size = 0;
int *arrPTR = readArray(size);
///....Do stuff here with arrPTR
delete arrPTR[];
After update:
int* readArray(int size); ///input only! need the & in the declaration to match
///the function body!
Is wrong, since you have your actual definition with the int &size.
You also don't declare arrPTR in readArray, just assign it.