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.
Related
I am trying to multiply array elements with 5 but I am getting the error of core dumped and if not, then, it only multiplies 5 with first element.
Here the code:
#include <iostream>
using namespace std;
int ptr_multiply(int[],int);
int main(){
int size;
cout<<"Enter the size of an array ==";
cin>>size;
int arr[size];
cout<<"Enter the elements of array ==";
for (int i=0;i<size;i++){
cin>>arr[i];
}
ptr_multiply(arr,size);
}
int ptr_multiply(int a1[],int s1){
int *ptr;
for (int i=0;s1;i++)
{
*ptr=a1[i];
ptr*=5;
cout<<"The Elements"<<" "<< i <<" "<<" after multiplying 5 is =="<<*ptr;
}}
*ptr=a1[i];
ptr*=5;
First line: You dereference a pointer that points nowhere (it is uninitialized). That is wrong and causes undefined behavior. You try to assign to an int when there is no int.
Second line: You do not dereference the pointer. You multiply the value of the pointer by 5 when you actually want to multiply the int it points to by 5 (remember: there is no int it points to).
You do not need a pointer here:
for (int i=0;i < s1;i++) {
int value = a1[i];
value *= 5;
cout<<"The Elements"<<" "<< i <<" "<<" after multiplying 5 is =="<<value;
}
Also the condition was wrong. It should be i < s1.
Last but not least, dont use C-arrays in C++. They are difficult to use and error-prone. Prefer std::array for fixed size arrays and std::vector for dynamic size. Actually int arr[size]; is not standard C++, see Why aren't variable-length arrays part of the C++ standard?
I have a function that adds integers to an array. If space runs out it should double the array size and add the value at the next free spot. So if the array size is 3 for example and I enter 99, 105, and 45. Now if I want to add 100 a new array of size 6 should be created. There is a snippet of the code below. It all works and I even display array[4] within the local function it returns 100. When the program returns to main to display the menu again all the values become -572662307. I spent days attempting to figure this out but could not. can anyone help?
//Snippet from Main
cout<<"Enter the size of the array to be created";
cin >> size;
int *myArray = new int[size]();
add(myArray,Size);
//Problematic Code
void add (int Array[], int size){
int* temp = new int[size*2]; // create new Array 2x The Size
for (int i = 0; i < size; i++) {
temp[i] = Array[i];//Copy data over
}
delete [] Array;//Delete the old array
Array = temp;
cout << "\n\nEnter a Number: ";
cin >> newNumber;
Array[sizeTrack] = newNumber;
sizeTrack = sizeTrack++;
If this is a school assignment and you can't use std::vector, then you need to know that by declaring an argument as int Array[], it's really the same as int* Array. What you have is a pointer, and when calling the function you pass a copy of the pointer.
That last part is important: You pass a copy of the value in the variable. That means, when you modify the argument variable inside the function, you only modify the copy. And modifying a copy leaves the original unmodified.
There are two possible solutions here, both which you should either already know about (go through your text-books and class notes) or should be able to find in your text-book:
Returning the new pointer.
Passing the argument by reference.
This question already has answers here:
Accessing an array out of bounds gives no error, why?
(18 answers)
Closed 5 years ago.
I made a code in which I had to take the size of an array as the user’s input and its elements too and print them.
#include <iostream>
using namespace std;
//Compiler version g++ 6.3.0
int main()
{
int i;
cout<<"\nenter the size of array";
cin>>i;
int n[i];
for(int j=0;j<=i;j++)
{
cout<<"\nn["<<j<<"]=";
cin>>n[j];
}
for(int k=0;k<=i;k++)
{
cout<<endl;
cout<<"\nn["<<k<<"]=";
cout<<n[k];
}
}
Suppose in the following:
The value of i is 3 (according to user’s input).
In the first loop the condition for j is up to <=i where i is the size of array (this shouldn't happen as i begins from 0) due to which the Compiler asks me to input 4 values for the array (n[0], n[1], n[2] and n[3]) but the size of the array is 3 only. How can it store 4 objects?
Change this:
for(int j=0;j<=i;j++)
to this:
for(int j = 0; j < i ; j++)
since array indexing ends at the size of the array minus 1. In your case i - 1.
Likewise, you neeed for(int k=0;k<i;k++).
Your posted code invoked Undefined Behavior, by accessing the array out of bounds.
This:
int n[i];
is a Variable Length Array (VLA), which is not Standard C++, but is supported by some extensions.
and if you compiled with pedantic flag, you would get:
prog.cc: In function 'int main()':
prog.cc:9:9: warning: ISO C++ forbids variable length array 'n' [-Wvla]
int n[i];
^
If you want something like this data structure, then I suggest you use an std::vector instead, which is Standard C++.
By the way, it's not a syntax error or something, but i is usually used as a counter (like you used j), an index if you like. As a result, I would chnage it's name to size, for instance, or something related.
EDIT:
Example with std::vector and variable renaming:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int tmp, n;
cout<<"Input number of elements\n";
cin >> n;
vector<int> v;
for(int i = 0; i < n; ++i)
{
cin >> tmp;
v.push_back(tmp);
}
for(auto number: v)
cout << number << endl;
return 0;
}
You need to check for less than i and not less than equal i. Otherwise it will try to store value for 0,1,2,3 in that case the last object will cause memory corruption. In c++ it will not give you any error even if you try to add 100 members in array of size 3.
It better you read memory management in c++ before jumping into coding.
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.
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<>!