C++ delete[] array; [duplicate] - c++

This question already has answers here:
C++ after delete pointer
(4 answers)
Closed 6 months ago.
#include <iostream>
#include <string>
using namespace std;
void print(string data[], int size) {
cout << "Print array" << endl;
for (int i=0; i<size; i++) {
cout << data[i] << ", ";
}
cout << endl;
}
int main(int argc, char** argv) {
string arr1[] = {"Apple", "Banana", "Coconut", "Durian"};
string *arr2 = new string[6];
arr2[4] = "Eggplant";
arr2[5] = "AppleBanana";
std::copy(std::begin(arr1), std::end(arr1), arr2);
print(arr2, 6);
delete[] arr2;
print(arr2, 6);
return 0;
}
I was wondering why delete[] arr2; only free up the arr2[0] because after I print it again only the first element in arr2 is freed but the rest still got the elements
I don't quite understand the free()/delete yet so it would be nice if someone also help explain it. I have been asking professor about it and I'm still confused as to why freeing up arr2 still got elements in its

Maybe, it is better to delete array in this way
for(int i = 0; i < size; i++)
{
delete [] arr2[i];
arr2[i] = nullptr;
}
Also you are not allowed to use the deleted arr2 after you used the keyword delete because it will cause some problems in time of and after compilation

Related

Dynamically allocated array C++ reads a sentence and prints the words

On the input we get a sentence which we read until EOF. We need to add single words to dynamic array and then write them one on each line.
Input: Hello this, is an example.
Output:
Hello
this,
is
an
example
I have the following code and I can't figure out why it doesn't even add anything to the array.
#include <iostream>
#include <string>
using namespace std;
void addToArray(string newWord, string myArray[], int& arrayLength)
{
string * tempArray = new string[arrayLength + 1];
tempArray[arrayLength] = newWord;
for (int i = 0; i < arrayLength; ++i)
{
myArray[i] = tempArray[i];
}
arrayLength++;
myArray = tempArray;
delete [] tempArray;
}
int main()
{
string * arrayOfWOrds = new string[1000];
int arrayLength = 0;
string temp;
while (getline(cin, temp))
{
cout << temp << endl;
addToArray(temp, arrayOfWOrds, arrayLength);
}
cout << "Array" << endl;
for (int i = 0; i < arrayLength; ++i)
{
cout << arrayOfWOrds[i] << endl;
}
}
It's because you don't return the new array from the addToArray function. The change you make only happens in addToArray, it doesn't happen in main.
You also delete[] the wrong array, you delete the array you've just created.
You also copy the array elements in the wrong direction, i.e. from your new array to your old array.
Try this, I've renamed some of the variables for clarity. There is no temporary array in your function only a new array and an old array. Choosing good variable names is very important for writing working code. Bad variable names just confuse yourself.
string* addToArray(string newWord, string* oldArray, int& arrayLength)
{
string * newArray = new string[arrayLength + 1];
newArray[arrayLength] = newWord;
for (int i = 0; i < arrayLength; ++i)
{
newArray[i] = oldArray[i];
}
arrayLength++;
delete [] oldArray;
return newArray;
}
Then use it like this
arrayOfWOrds = addToArray(temp, arrayOfWOrds, arrayLength);
I see several issues here. To begin with, you set arrayLength = 0, so it's not going to iterate over the whole array if you have stuff already in it. If you don't have anything in it, there's no point in making it start off with 1000 items. Also, while (getline(cin,temp)) is an infinite loop, so it will never end and actually print the array. If you want to print the array after each addition, you need to move it into the while loop. There's no real reason to cout the number the user types either; they can already see the line they just typed.
More importantly, there are real issues with the dynamic allocation. You've created a static array (string * arrayOfWOrds = new string[1000];), then you're giving that to the function which makes a new array one item larger, sets the last item in that array to the new value, then iterates over the entire new array and duplicates the values to the old array. Basically, you're just inserting items into the static array at that point, and what you're inserting is a bunch of nothing (because the new array only has one item in it, and it's at arrayLength+1 which is outside the bounds of the original array).
You need to delete the old array, not the new array, which actually should be thrown on the heap and returned.
Basically, it should look more like this:
#include <iostream>
#include <string>
using namespace std;
string* addToArray(string newWord, string myArray[], int& arrayLength)
{
string * returnArray = new string[arrayLength + 1];
returnArray[arrayLength] = newWord;
for (int i = 0; i < arrayLength; ++i)
{
returnArray[i] = myArray[i];
}
arrayLength++;
delete [] myArray;
return returnArray;
}
int main()
{
const int startSize = 0;
string * arrayOfWords = new string[1];
int arrayLength = startSize;
string temp;
cout << "Input: ";
getline(cin, temp);
string word = "";
for (char c : temp){
if (c == ' '){
arrayOfWords = addToArray(word, arrayOfWords, arrayLength);
word = "";
} else word.push_back(c);
}
arrayOfWords = addToArray(word, arrayOfWords, arrayLength); // Don't forget the last word
for (int i = 0; i < arrayLength; ++i)
{
cout << arrayOfWords[i] << endl;
}
}
The array is unchanged, because you pass the pointer to the addToArray function, but it has no way to pass the new pointer back. You can fix this by changing the signature of the function to
void addToArray(string newWord, string *myArray[], int& arrayLength)
You also need to change the code accordingly, and fix problem with deallocation.
You can save yourself all the trouble and use std::vector in place of manually allocated dynamic array:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
vector<string> arrayOfWOrds;
string temp;
while (getline(cin, temp))
{
cout << temp << endl;
arrayOfWOrds.push_back(temp);
}
cout << "Array" << endl;
for (size_t i = 0; i < arrayOfWOrds.size(); ++i)
{
cout << arrayOfWOrds[i] << endl;
}
}
string in="dasd adas ads adsada adsa asd ads",out;
stringstream ss(in);
vector<string> vr;
while(ss>>out)
{
vr.push_back(out);
//cout<<out<<endl;
}
for(int i=0;i<vr.length();i++)
{
cout<<vr[i]<<endl;
}
try doing this

Having trouble with my C++ program. Involes resizing an integer array dynamically

Here is what I have so far: http://cpp.sh/54vn3
#include <iostream>
#include <string>
#include <cmath>
#include <iomanip>
#include <cstdlib>
using namespace std;
int *reSIZE(int *&original, int &SIZE, const int &maxSIZE); //function prototype resize
void sortFUNC(int *&original, int &SIZE, const int &maxSIZE); //function prototype sortFUNC
int main()
{
int SIZE = 4; //size of current array
int maxSIZE = 10; //size of final array
int *original = new int[SIZE] {5, 7, 3, 1}; //old(current) array
cout << "Elements in array: "; //test output
reSIZE(original, SIZE, maxSIZE); //call function resize
cout << endl << endl; //blank line
cout << "Elements in array in increasing order: "; //test output
sortFUNC(original, SIZE, maxSIZE); //call function sortFUNC
cout << endl << endl;
return 0;
}
int *reSIZE(int *&original, int &SIZE, const int &maxSIZE)//function definition
{
int *temporiginal = new int[SIZE + 3]; //(final)new array
for (int i = 0; i < SIZE; i++) //copy old array to new array
{
temporiginal[i] = original[i];
cout << original[i] << setw(3);
}
delete[] original; //delete old array
original = temporiginal; //point old array to new array
return temporiginal;
}
void sortFUNC(int *&original, int &SIZE, const int &maxSIZE)
{
for (int i = 0; i < SIZE; i++)
{
int smallest = original[i];
int smallestINDEX = i;
for (int m = i; m < SIZE; m++)
{
if (original[m] < smallest)
{
smallest = original[m];
smallestINDEX = m;
}
}
swap(original[i], original[smallestINDEX]);
}
int *temporiginal = new int[SIZE + 3];
for (int i = 0; i < SIZE; i++)
{
temporiginal[i] = original[i];
cout << original[i] << setw(3);
}
delete[] original;
original = temporiginal;
}
I want to add a few elements at the end of the array in main, but when I do, the program crashes when I run it. The resize function that I created is supposed to expand the function in main to hold 10 elements. The one in main originally holds 4. The new array is supposed to change that to 10. How do I add three more integers to the array in main without it crashing? Is my resize function wrong? Or is it a problem in my main? The program that is shown right now works as is. But when I add another integer in the array in main, it crashes. Like, if I add a 2 after the 1.
Thanks.
Edit: I was able to add elements at the end of the array in main by adding them in the resize function.
cpp.sh/35mww
Like mentioned earlier, maxSIZE isn't being used. There are more useless stuff as well. I have to clean this up, but I figured out what I was trying to figure out. I don't know how to use structures yet. I know that there are a lot of different ways to write a program. I'm just a beginner.
Thanks, everyone.
You need to modify the value of size everytime you call the function rezise other wise even if u call the function resize 3 times u always will have SIZE+3 on your array size.After call resize try
original[4] = 0;
original[5] = 0;
original[6] = 0;
and after that try to do this.
original[7] = 0;
you should be able to see your mistake

Creating dynamically allocated arrays using Xcode's g++

So, I recently tried doing this:
void Foo(int **bar, int size) {
bar = new int *[size];
for (int i = 0; i < size; i++)
bar[i] = new int[4];
// Do other stuff
return;
}
int main(int argc, char *argv[]) {
int ** data;
int size = atoi(argv[1]);
Foo(data, size);
for (int i = 0; i < size; i++) {
for (int j = 0; j < 4; j++)
cout << "i = " << i << ", j = " << j << ", data = " << data[i][j] << endl;
// Do other stuff
}
for (int i = 0; i < size; i++)
delete[] data[i];
delete[] data;
return 0;
}
and invariably I would get a segfault right at that cout statement. After changing the code so that the array was dynamically allocated in main the problem went away. So, the difference between a segfault is whether or not an array is dynamically allocated and destroyed in the same function. This seems wrong to me as this shouldn't be a problem with traditional C++. I am using a MacBook with Xcode for the g++ command. Can anyone else confirm that Xcode's implementation does this?
It's nothing specific to Xcode or g++ - just a bug in your code - you need to pass bar by reference in order to use it as an output parameter.
Change:
void Foo(int **bar, int size)
to:
void Foo(int ** &bar, int size)
Note that in general it's preferable to use e.g. std::vector rather than naked C-style pointers for arrays etc.
You pass data to Foo by value, so data in main () remains uninitialized when you allocate memory inside Foo.

Return an array of compared char pointers in C++ [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 8 years ago.
I'm at college and we're learning pointers. Our job was to input a char, compare it to an array and return a pointer to the first reference of that char in the array. But, as I don't like easy things, I've asked my teacher what about having that char more than once in the array.
That's where my headache begins.
So I have this code. The idea is: create a function that compares the input char to the entire array, get the pointers of the references and save them in an array and return that array.
Unfortunately it's not working as I wish :(
What can be wrong?
#include<iostream>
#include<cstdlib>
using namespace std;
char list [10];
int main()
{
initialize();
show();
cout<<search('1');
}
void initialize()
{
int i;
for(i=0; i<10;i++)
{
list[i]='1';
}
}
void show()
{
int i;
for(i=0; i<10;i++)
{
cout<<list[i];
}
}
int* search(char* input)
{
int* result[10];
int i;
char *temp;
for (i=0; i<10; i++)
{
*temp=list[i];
if(strcmp(temp, input) != NULL)
{
result[i]=i;
}
}
return result[];
}
I'm on a mobile device so I can't go into huge detail unfortunately, but you are returning a pointer to an array that you create in the function which goes out of scope at the end of the function.
My massive edit:
As everyone has already stated, a C++ array is actually only a pointer to the first element in the array. As a result, if you return a pointer to an array created in the scope of the function, you are returning a pointer to garbage. If I were doing this I would use a vector, but if I were to be forced into using an array, I would use something like the code below. Hope this helps!
#include <iostream>
#include <cstdlib>
void initialize(char* list) {
for(int i = 0; i < 10; ++i) {
if(i < 4) {
list[i] = '2';
} else {
list[i] = '1';
}
}
}
void show(char *list) {
for(int i = 0; i < 10; ++i) {
std::cout << list[i] << ' ';
}
std::cout << std::endl;
}
// Note the function requires an additional argument that is a pointer
// this is how you can avoid returning a pointer
int search(char input, char* list, char* result) {
int j = 0;
for(int i = 0; i < 10; ++i) {
// comparing characters can be done via ==
if(input == list[i]) {
*(result + j) = list[i];
// You could use result[j], but I used this to show that
// result really is just a pointer to the first element
// of the array. As a result saying result[j] is the same
// as saying I want to deference j elements past the first
// element or *(result + j)
++j; // increment j
}
}
// return how many elements matched
return(j);
}
int main(int argc, char *argv[]) {
char list[10];
char temp[10];
initialize(list);
show(list);
int size = search('1', list, temp);
// create a dynamically sized array containing space for each match
// because we don't know the size at compile time we must use
// a library type or a dynamically sized array
char *result = new char[size];
for(int i = 0; i < size; ++i) {
result[i] = temp[i];
// again you could use result[i]
std::cout << *(result + i) << std::endl;
}
delete[] result; // otherwise you'll get a memory leak
return(0);
}

C++ the dynamic array and file reading don't work together

Such a code:
int _tmain(int argc, _TCHAR* argv[])
{
int *test = new int[];
ifstream f("ofile.txt");
for (int i=0,v; i<10; i++)
{
f>>v;
test[i]=1;
cout<<"\nv = "<<v<<", i = "<<i<<endl;
}
return 0;
}
caused of this message after compiling:
I guess (correct me if I'm wrong) here is some error about memory, but details are unknown for me. If I remove one of them (file reading or array) it works.
So it will be great to hear an explanation of the problem.
You're thinking java. To allocate an array like that you need to give a size.
e.g.
int *test = new int[20];
However a better scheme would be to use a vector of integers.
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm> // for sort()
int main(int argc, char *argv[])
{
std::vector<int> data;
std::ifstream fsin("ofile.txt");
int count = 0;
while (fsin.good())
{
int v;
fsin >> v;
if (fsin.good())
{
data.push_back(v);
std::cout << "\nv = " << v << ", i = " << count++ << std::endl;
}
}
std::sort(data.begin(), data.end());
for (size_t i=0; i<data.size(); i++)
std::cout << i << '\t' << data[i] << std::endl;
return 0;
}
You have to allocate a fixed size array, int *test = new int[]; shouldn't even work.
If the size is known, use int *test = new int[size];, otherwise try using a std::vector or std:array.