Problem outputting dynamic array from function [closed] - c++

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
the function is to preserve argument array and produce anidentical array in the heap memory that has the even elements to (left) & odd(right), but when i output i find a row of zeros and bunch of random big numbers which look like addresses but I don't think they are, Please help.
int* even_left_odd_right(int arr[], int size1)
{
int* array;
array = new int[size1];
for(int i = 0; i < size1; i++)
array[i] = arr[i];
for(int i = 0, j =0; i < size1; i++)
{
if(array[i] % 2 == 0)
{
int temp = array[j];
array[j] = array[i];
array[i] = temp;
j++;
}
}
return array;
}
int main()
{
int size1;
cout << "Enter size of array:";
cin >> size1;
int* array1;
array1 = new int[size1];
int arr[size1];
cout << "Enter the entries in this array: ";
for(int i = 0; i < size1; i++)
cin >> arr[i];
even_left_odd_right(arr, size1);
for(int i = 0; i < size1; i++)
cout << array1[i] << " ";
delete[] array1;
return 0;
}`

The root cause of all your problems is that you do not use the return value of your function. Besides that, there are more things that should be corrected.
Additionally, we need to mention that what you are obviously learning now, dynamic memory management using new and delete and raw pointers for owned memory, is strongly discourage.
Basically: new, delete and raw pointers for owned memory should NEVER be used in C++.
It is that error prone that is has no place any more in standard C++. You even have an error with leaked memory and do not notice it. The array, that you are dynamically allocating in your function with new, is never deleted.
I know that teachers still do teach this crap, but just for explaining dynamic memory mangement from scratch. So, let's go ahead and use it for now.
You have however some additional errors.
Your function returns the partitioned data. But you never use the functions return value
You are using (for whatever reason??) a so called VLA (Variable Length Array) in int arr[size1];. This is illegal in C++. Real C++ compilers will not allow that.
You are mixing up arr and array1. In the beginning, you are creating array1. After creation, it is not initialized and will contain random values.
Then you call your function with arr and output array1 at the end. So, you will output random data. That is, what you see. Random data.
You could use the build in std::swap function. But I guess that it is prohibited by the teacher. What a shame.
You unneccessarily change the order of the entries in the array with swapping. But this does not harm
Your function simply returns a raw pointer. The outer world does not know anything about that. That is dangerous
You even do not know that arr in your function signature (int arr[]) will decay to a pointer
To quickly fix your code, we could write:
#include <iostream>
int* even_left_odd_right(int arr[], int size1)
{
int* array;
array = new int[size1];
for (int i = 0; i < size1; i++)
array[i] = arr[i];
for (int i = 0, j = 0; i < size1; i++)
{
if (array[i] % 2 == 0)
{
int temp = array[j];
array[j] = array[i];
array[i] = temp;
j++;
}
}
return array;
}
int main()
{
int size1;
std::cout << "Enter size of array:";
std::cin >> size1;
int* array1;
array1 = new int[size1];
//int arr[size1]; NOT ALLOWED in C++
std::cout << "Enter the entries in this array: ";
for (int i = 0; i < size1; i++)
std::cin >> array1[i];
int* array2 = even_left_odd_right(array1, size1);
for (int i = 0; i < size1; i++)
std::cout << array2[i] << " ";
delete [] array1;
delete [] array2;
return 0;
}
But such code should never be used in C++.
Again, I guess I understand requirements from teacher.
By the way. In C++17 you would probaly write the follwoing code:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
int main() {
// Tell user, what to do: Get the number of data to operate on
std::cout << "\nEnter the number of data to operate on: ";
// Read the number of data from the user via std::cin. Check, if number is OK
if (size_t numberOfData{}; (std::cin >> numberOfData) and (numberOfData > 0)) {
// Define the vector for our original data with the size given by the user
std::vector<int> dataOriginal(numberOfData);
// And get the number of specified data from the user
std::cout << "\n\nAnd now, please enter the data\n";
std::copy_n(std::istream_iterator<int>(std::cin), numberOfData, dataOriginal.begin());
// We want to preserve the original input, so, make a copy of that vector
std::vector result(dataOriginal);
// Now partition the output as requested
std::stable_partition(result.begin(), result.end(), [](const int i) { return (i % 2) == 0; });
// Show result to user
std::copy(result.begin(), result.end(), std::ostream_iterator<int>(std::cout, " "));
}
else {
std::cerr << "\nError: Wrong input given for number of data\n\n";
}
}
Please note:
No loops
Input validation
CTAD
No function needed, everthing can be done with one statemennt

Related

Garbage value when trying to remove value from dynamic array

i keep getting garbage value on one of the indexes in the dynamic array when i try to remove a value which was entered by user from a list of elements in the dynamic array.
used pointer as function parameters and replaced the value to be removed with 0 and by using a counter and for loop tried to skip all the 0s but in place of zero theres a garbage value.
#include<iostream>
#include<fstream>
using namespace std;
int size = 0;
int final = 0;
int* read(ifstream& a){
int temp;
a.open("data(1).txt");
while (!a.eof()){
a >> temp;
size++;
}
a.close();
a.open("data(1).txt");
int* arr = new int[size];
for (int i = 0; i < size; i++)
a >> arr[i];
return arr;
}
int* remove(int* a,int search){
for (int i = 0; i < size; i++){
if (a[i] == search)
a[i] = 0;
else final++;
}
int* change = new int[final+1];
for (int i = 0; i < size; i++){
if (a[i] > 0){
change[i] = a[i];
}
else continue;
}
delete[] a;
a = nullptr;
return change;
}
int main(){
int* ptr = nullptr;
int num;
cout << "please enter the number to remove: ";
cin >> num;
ifstream in;
ptr=read(in);
ptr=remove(ptr, num);
for (int i = 0; i < final; i++)
cout << ptr[i] << " ";
cout<<endl;
system("pause");
return 0;
}
There is much to discuss and critize about your code. Also your question is very unclear because we do not have your input file, nor do you tell us what the code should actually do. However, I will leave all "please write actual c++ rather than c without classes" aside and just point you to the one critical mistake:
This loop
int* change = new int[final+1];
for (int i = 0; i < size; i++){
if (a[i] > 0){
change[i] = a[i];
}
else continue;
}
And then this loop
for (int i = 0; i < final; i++)
cout << ptr[i] << " ";
It seems like you want to copy all elements that are >0 to change. Or maybe you want to copy all, its really hard to tell, because broken code is just broken, it does not explain itself. Anyhow...
The first loop leaves all elements change[i] where a[i] <= 0 uninitialized. The values at those indices i are indeterminate. There isn't really a value you can read. Attempting to read an indeterminate value results in undefined behavior.
You are attempting to read all elements of change, but some of them are not initialized, they are indeterminate values. Hence your code has undefined behavior.
There are other situations the will bring your code into bad states, like for example search not begin found in the input array or a[i] > 0 for some i > final. Though, I don't see a possiblity for any input to your code that would not eventually invoke undefined behavior.
You sould use a debugger to see where your code is doing something unexpected.

The program crashes sometimes and works perfectly fine sometimes. A variable array is declared and its size changes 2 times in the program

The program crashes sometimes and works perfectly fine sometimes. A variable array is declared and its size changes 2 times in the program. I am using visual studio. It is in c++.
This is the code in c++:
int sz; //size of array
std::cin >> sz; //getting size
int* arr = new int[sz]; //declaring variable array.
for (int i = 0; i < sz; i++)
{
arr[i] = i; //assigning values to all members of array
std::cout << arr[i] << std::endl; //printing the array
}
std::cin >> sz; //size changes again
for (int i = 0; i < sz; i++)
{
arr[i] = i; //assigning new values
std::cout << arr[i] << std::endl; //printing the array
}
On this line:
std::cin >> sz; //size changes again
The comment is not really correct. The variable representing the size is changed, but the array arr is not changed. So indexing into any position greater than or equal to the old size will invoke undefined behavior. This means the program may work sometimes, and not others.
To resize the arr array, after the above line you need to do:
delete [] arr;
arr = new int[sz];
If you want to resize arr you must delete the old one and allocate a new one
delete[] arr;
arr = new int [sz];
If you allocate a vector with new you should delete it after you no longer need it, and don't reuse it arbitrarily so your code would be better as:
int sz; //size of array
{
std::cin >> sz; //getting size
int* arr = new int[sz]; //declaring variable array.
for (int i = 0; i < sz; i++)
{
arr[i] = i; //assigning values to all members of array
std::cout << arr[i] << std::endl; //printing the array
}
delete [] arr; // << Delete old one here, missing in original
}
{
std::cin >> sz; //size changes again
int* arr = new int[sz];
for (int i = 0; i < sz; i++)
{
arr[i] = i; //assigning new values
std::cout << arr[i] << std::endl; //printing the array
}
delete [] arr; // <<--- Here as well, missing in original - less important, but leads to memory leak.
}
or just use std::vector<int> arr(sz); and you can ignore the delete. If you absolute need to re-use the array use arr.resize(sz);

Accessing and modifying 2D dynamically allocated arrays

I'm trying to create a 2D array of c-strings (for a specific school exercise; I'm forced to use c-strings for practice) using dynamic memory allocation. However, it seems that when accessing and writing to the second index of the array (second sub-array), the actual memory location that's used is the same of the first index.
The code:
#include <iostream>
#include <string>
int main()
{
int n_names; std::string current; const int SPACE_FOR_EACH_NAME = 100;
std::cout << "How many names to input? "; std::cin >> n_names; std::cin.ignore();
//dynamically allocate a multi-dimensional array
char** names;
names = new char* [n_names];
for (int i = 0; i < n_names; i++)
names[i] = new char[SPACE_FOR_EACH_NAME];
int count = 0;
while (count < n_names) {
std::cout << "Name " << ++count << ": ";
std::getline(std::cin, current);
names[count-1] = (char*) current.c_str(); //THE TROUBLE SEEMS TO BE HERE
}
for (int i = 0; i < n_names; ++i) {
for (int j = 0; j < SPACE_FOR_EACH_NAME; ++j) {
if (names[i][j] == '\0') break; //termination of the current name
std::cout << names[i][j];
}
std::cout << "\n";
}
//free allocated memory
for (int i = 0; i < n_names; ++i)
delete[] names[i];
delete[] names;
}
What the debugger shows when modifying the 'names' array (consider user inputs 2 names):
+ names[count-1] 0x00affbe8 "dude" char * //here count is 1
+ names[count-1] 0x00affbe8 "noice" char * //here count is 2
And the console just prints "noice" twice.
What's wrong?
The result of current.c_str() should never be stored for any length of time. Doing so is undefined behaviour, but it is likely, as here that that memory pointed to will be reused.
You put the char* from current.c_str() into names[0], then you put a new value into current and put current.c_str() into names[1]. But because you have changed current you also change names[0].
Also, in both cases, you are discarding the pointer you already created with names[i] = new char[SPACE_FOR_EACH_NAME];
This allocates a block of memory and puts it's address into names[0] (0 as a specific example). The next thing that happens with names[0] is names[0] = (char*) current.c_str(); which puts a different address into the variable. The address returned from the new is lost completely, causing a memory leak.
Instead of
names[count-1] = (char*) current.c_str();
try
std::strcpy(names[count-1],current.c_str())

Invalid conversion error when trying to keep array from changing when called by a function

For this assignment, I need to make a sorted copy of an array the user has given values to. All of my code works as intended, except for this specific part. I need this function (sortedCopy) to print out the sorted version of their array, without actually changing the array itself. As far as I can tell, to do so I need to used a constant version of the array in the function so the prototype would be something like: int *sortedCopy(const int *array, int size), but all this does is give the error shown in the title. Specifically:
main.cpp:72:29: error: assignment of read-only location '*(array +
((sizetype)(((long unsigned int)i) * 4)))' array[i] = array[min]
and it does this error twice, except with array[min] = temp; at the end instead
This is the code used, with the relevant parts of main:
#include <iostream>
using namespace std;
int* sortedCopy(const int *array, int size) {
int i, j, min, temp;
for (i = 0 ; i < size - 1; i++) {
min = i;
for (j = i + 1; j < size; j++) {
if (array[j] < array[min]) {
min = j;
}
}
temp = array[i];
array[i] = array[min];
array[min] = temp;
}
cout << "Sorted array is: " << endl;
for(int i = 0; i < size; i++) {
cout << array[i] << " ";
}
cout << endl;
// Not sure if I need to return anything or not either
}
int main() {
cout << "Please enter the size of the array." << endl;
int arraySize;
int array[arraySize];
cin >> arraySize;
cout << "Please enter integer values until the array is filled." << endl;
for (int i = 0; i != arraySize; i++) {
cout << "Value " << (i + 1) << ": ";
cin >> array[i];
cout << endl;
sortedCopy(array, arraySize);
for (int i = 0; i != arraySize; i++) { // I want this part to print the
cout << array[i] << " "; // original array entered by the user
}
}
If I remove the const part of the function, it works totally fine, except it will print the sorted array after the function is called, instead of the original array.
Firstly, C/C++ is best read "top-down":
int arraySize;
int array[arraySize]; // arraySize is undefined here!!
cin >> arraySize;
On the second line, ArraySize, might be 1, or 0, or -1000. You haven't defined it until line 3.
Also, C++ doesn't allow you to allocate arrays of variable size (unless that size is const [ so it is known at compilation time]):
int array[4];
The above is fine. This helps the operating system know how much memory to provide for you on the stack (it needs to do this before your programme starts running).
const int arraySize = 4;
int array[arraySize];
Because the C++ compiler knows that arraySize is 4, it processes this just like the above code, so this is also fine.
So to handle arrays of genuinely variable length (length that depends on inputs), you need to first read the user inputs, then use dynamic allocation ("new", or a container that does dynamic allocation for you, like a vector).
As for the problem with "const", what I think that you need to understand here is that "const" is really just a promise from the programmer: The programmer is communicating to the compiler (and any programmers reading the code) that this data is not supposed to change. All the compiler does is check whether you keep your promise (or if you send it to another function / pointer that doesn't hold that promise). So by using "const" there is no work done being done for you to actually keep the data constant - just that it will complain if you don't do the work.
int* sortedCopy(const int *array, int size) {
Above you're flagging to the compiler that the sortedCopy function will keep the data in the array constant.
array[i] = array[min];
array[min] = temp;
And here (above) you are breaking that promise.
If you don't want to edit the original array, then the easiest solution is just to copy it before you send it to your sorting function.

Program declaring variables by itself

I am still a ... novice, in c++.
I don't know the name of what I am looking for but
I 've been searching a lot but can't seem to find the answer to following question:
I want to write a program that would declare demanded number of variables.
Example:
int a;
cin>>a;
Now if "a" is 5 (or any other number), I want program to declare 5 more variables,
Names do not matter but let's say...n1,n2,n3,n4,n5.
I've tried array and for loop but can't get it to work.
I got answer on Croatian forum (forum.hr) but the forum is currently offline, so I had no
time to try it out...
It was about using heap instead of stack
Thx in advance
C++ has container classes for this purpose. In particular, you want a vector:
std::vector<int> a(size);
for (int i = 0; i < a.size(); ++i)
std::cin >> a[i];
Declares a vector a of integers of some size and reads its elements, one by one.
If this is C++, the best you can do is using std::vector as it will manage the memory for you.
you can store them in an array:
int a;
cin >> a;
int *number = new int[a]; // allocate an array of size a
for (int i = 0; i < a; i++) {
number[i] = 5 + i; // set your numbers to anything here
}
delete[] number; // otherwise you have memory leak
or better use a vector:
vector<int> number(a);
// iterate with a normal for loop
for (int i = 0; i < number.size(); i++) {
number[i] = 5 + i;
}
..
// or use iterators
for (vector<int>::iterator it = number.begin(); it != number.end(); ++it) {
cout << *it << endl;
}
so you don't have to manage memory.