I have this function in order to expand the size of my char **array that I use in two other functions, which is why I'm passing it in by reference. I know I'm supposed to delete array at some point because it's dynamically allocated in this function, but I cant delete it until after I'm done using it in my code. However, valgrind still says memory is definitely lost in the line which contains array = new char *[cap2]. How should I go about deleting this?
void expand(int &size2, int &cap2, char **&array){
int i;
if(size2 ==1)
{
cap2 = size2;
cap2 = cap2*2;
array = new char*[cap2];
for(int n=0; n<cap2; n++)
{
array[n] = '\0';
}
}
else{
cap2 = cap2 *2;
char **temp;
temp = array;
array = new char*[cap2];
for(i =0; i<size2 ; ++i)
{
array[i] = temp[i];
}
for(int k = size2; k<cap2; k++)
{
array[k] = '\0';
}
}
return;
}
Related
I am trying to make a dynamically growing array which increases in size every time the user enters any integer other than 0. When 0 is pressed, it stops taking data from user and the rest of the code is executed.
I tried to implement the growing array through a do while loop but it keeps giving me garbage values in my array.
int main(){
int size = 1;
int* ptr;
int* ptr1;
int i = 0;
int inp;
ptr = new int[size];
do{
ptr1 = new int[size];
cin >> inp;
if (inp == 0)
break;
else{
*(ptr + i) = inp;
size++;
i++;
for (int j = 0; j < size; j++){
*(ptr1 + j) = *(ptr + j);
}
}
} while (1);
for (int k = 0; k < size; k++)
cout << *(ptr1 + k) << endl;
system("pause");
return 0;
}
When you exit the loop you have already reserved memory again. That is, you have put ptr1 pointing to a memory address of size integers that you have not yet initialized. Also note that when you write *(ptr + i) = inp; you are trying to write to memory that you have not allocated. This is because although you increment ptr1, you do not do the same with ptr.
I have written a class with char** class field(which is dynamic 2d array) named visa(basically i want there to be countries which a person has visited) and countriesVisited(in fact size of the array). I intentionally didn't use strings. I've added a class method, which adds countries to the mentioned array, but when i try to delete the array elements i get HEAP CORRUPTION detected: after Normal block (#158):
void ForeignPassport::addCountry(const char* country) {
char** tmp = new char* [countriesVisited + 1];
for (int i = 0; i < countriesVisited+1; i++) {
tmp[i] = new char[strlen(country)];
}
for (int i = 0; i < countriesVisited; i++) {
int f = 0;
while (visa[i][f-1] != '\0') {
tmp[i][f] = visa[i][f];
f++;
}
}
for (int i = 0; i <= strlen(country); i++) {
if (i == strlen(country)) {
tmp[countriesVisited][i] = '\0';
break;
}
tmp[countriesVisited][i] = country[i];
}
countriesVisited++;
for (int i = 0; i < countriesVisited-1; i++) {
delete[]visa[i];
}
visa = tmp ;
}
tmp[i] = new char[strlen(country)];
here you are allocating memory in amounts of strlen(country)
but in this loop:
for (int i = 0; i <= strlen(country); i++) {
if (i == strlen(country)) {
tmp[countriesVisited][i] = '\0';
break;
}
tmp[countriesVisited][i] = country[i];
}
here you are accessing to the memory which is not allocated and this not allowed,
so change the condition to i < strlen(country)
I designed a dynamic array with an update function that deep copies the contents of the original into a temp array, then doubles the size then puts the contents of temp array into the new one.
This is the function:
T& operator[](const unsigned i)
{
if(i >= SIZE)
{
T *temp = new T[SIZE];
for(int i = 0; i< SIZE; ++i)
{
temp[i]=data[i];
}
delete[] data;
SIZE *= 2;
data = new T[SIZE];
for(int j = 0; j< SIZE; ++j)
{
data[j]=temp[j];
}
delete[] temp;
}
return data[i];
};
This function works with all data types except strings like:
Vector<string> s;
string str1 = "1";
string str2 = "2";
s[0] = str1;
s[1] = str2;
cout<< s[0]<< s[1]<< '\n';
However with ints for example:
Vector<int> in;
for(i = 0; i < 11; i++){
in[i] = i;
}
for(i = 0; i < 11; i++){
cout<< "int test"<< '\n';
cout<< in[i]<< '\n';
}
The update works perfectly fine.
anyone of you know why?
Thank you.
The following code seems to work when the array is declared like
int numbers[3]
But when I try declaring it like
int* numbers = new int[3];
After resizing the resized array's first two numbers seem to get lost.
I can't really figure out what is the difference betwean the two declarations. Any clarification will be helpfull.
int main() {
int numbers_size = 0;
int numbers_capacity = 3;
//works when declared like this
//does not work when declared like int* numbers = new int[3]
int numbers[3];
do {
...
if(numbers_capacity == numbers_size)
numbers_capacity = resize_array(numbers, numbers_size);
}while(numbers[numbers_size - 1] != 0);
return 0;
}
int resize_array(int* arr, int arr_size) {
int* temp = new int[arr_size];
for(int i = 0; i < arr_size; i++)
temp[i] = arr[i];
delete [] arr;
arr = new int[4*arr_size];
for(int i = 0; i < arr_size; i++) {
arr[i] = temp[i];
}
delete [] temp;
return 4*arr_size;
}
You are changing the value of arr in resize_array to point to new memory location but the calling function still has the old, now dangling, memory location.
Change the function to:
int* resize_array(int* arr, int arr_size)
{
int* temp = new int[arr_size];
for(int i = 0; i < arr_size; i++)
temp[i] = arr[i];
delete [] arr; // This makes pointer in the calling function
// point to deleted memory.
arr = new int[4*arr_size];
for(int i = 0; i < arr_size; i++) {
arr[i] = temp[i];
}
delete [] temp;
// Return the newly allocated memory.
return arr;
}
and use it like:
numbers_capacity = numbers_size*4; // This is bad. It assumes that
// that you are increasing the size by 4 times.
numbers = resize_array(numbers, numbers_size);
You can simply use a std::vector<int> and avoid all the headache.
I have problem with calling delete inside functions. When I allocate memory using new inside function it seem do work, but deleting formerly allocated memory causes throwing of std::bad_alloc. Is it even possible, or can I only free memory under "a" from inside of main?
#include <iostream>
using namespace std;
int size = 5;
void alloc (int* t, char**& a) {
t = new int [size];
a = new char* [size];
for (int i = 0; i < size; ++i)
a[i] = new char [size];
cout << "allocated\n";
}
void realloc (char**& a) {
for(int i = 0; i < size; ++i)
delete [] a[i];
delete [] a;
cout << "deleted\n";
a = new char* [size];
for (int i = 0; i < size+5; ++i)
a[i] = new char [size+5];
cout << "allocated\n";
}
void fillArray (char** a) {
for (int i = 0; i < size; ++i) {
for (int j = 0; j < size; ++j) {
a[i][j] = '.';
}
}
}
void printArray (char** a) {
for (int i = 0; i < size; ++i) {
for (int j = 0; j < size; ++j) {
cout << a[i][j];
}
cout << endl;
}
}
int main() {
int* t;
char** a;
alloc(t, a);
fillArray(a);
printArray(a);
size+=5;
realloc(a);
fillArray(a);
printArray(a);
}
You can call delete[] from anywhere. Your problems are much more prosaic. You just have a defect in your code.
You allocate an array of length size. Then you increment size. Then you do this:
for(int i = 0; i < size; ++i)
delete [] a[i];
And because you incremented size already, your loop runs off the end of a. You need to use the same value for size as was used when you allocated the array.
To be quite clear, the following is the flow of execution:
size is assigned to the value 5.
a is allocated with length 5.
size is incremented to the value 10.
You run a for loop from 0 to size-1, that is 0 to 9, and call delete[] a[i].
Clearly the iterations 5 to 9 inclusive are accessing elements of a that were not allocated. And that's undefined behaviour, and so on.
You could fix this by passing the new size to the realloc function as a parameter. Something like this:
void realloc (char**& a, size_t newsize) {
for(int i = 0; i < size; ++i)
delete [] a[i];
delete [] a;
size = newsize;
a = new char* [size];
for (int i = 0; i < size; ++i)
a[i] = new char [size];
}
Obviously you would not modify size outside of this function. You would call the function like this:
realloc(a, size+5);
Taking it a bit further, you might choose to handle the allocations like this:
size_t size = 5;
void alloc(char**& a, size_t newsize) {
size = newsize;
a = new char*[size];
for (int i = 0; i < size; ++i)
a[i] = new char[size];
}
void realloc(char**& a, size_t newsize) {
for(int i = 0; i < size; ++i)
delete[] a[i];
delete[] a;
alloc(a, size+5);
}
All that said, and being perfectly frank, your entire program is a disaster in the making. There are many other errors that I've not covered in this answer. Use standard containers like std::vector and std::string. The standard containers will handle the details of memory allocation, and will do it correctly.