Compiler error: invalid conversion from 'int' to 'int*' [-fpermissive]| - c++

I got a compiler error:
main.cpp|59|error: invalid conversion from 'int' to 'int*' [-fpermissive]|
The offending line is
int *pComienzo = vector, *pFinal = vector[nElementos-1];
Why there is an error? Can someone help me?
Below is my code:
#include <iostream>
#include <ctype.h>
using namespace std;
const unsigned short int MAX_VAL = 10;
int LongitudCadena(char*);
int BuscarCaracter(char *cadena, char caracter);
void Ordenar(int *vector, int nElementos, bool ascendente);
int main()
{
char *cadena = "asdasd";
cout << LongitudCadena(cadena) << endl;
cout << BuscarCaracter(cadena, 'a') << endl;
int iArray[] = {5,4,3,2,1};
Ordenar(iArray, 5, 1);
cout << iArray << endl;
return 0;
}
int LongitudCadena(char *cadena)
{
char *c = cadena;
for(int i = 0; i < MAX_VAL; i++)
{
if (c[i] == 0) break;
cadena++;
}
return cadena - c;
}
int BuscarCaracter(char * cadena, char caracter)
{
char *pCadena = cadena;
for (int i = 0; i < MAX_VAL; i++)
{
pCadena++;
if (toupper(cadena[i]) == toupper(caracter))
return pCadena- cadena;
}
return -1;
}
void Ordenar(int *vector, int nElementos, bool ascendente)
{
int *pComienzo = vector, *pFinal = vector[nElementos-1];
if (ascendente)
{
for (int i = 0; i < nElementos; i++)
{
for (; pComienzo < pFinal; pComienzo++, pFinal--)
{
if (*pComienzo > *pFinal)
{
*pComienzo += *pFinal;
*pFinal -= *pComienzo;
*pComienzo -= *pFinal;
}
}
}
}
}
I'm learning...

Your error is in this line:
int *pComienzo = vector, *pFinal = vector[nElementos-1];
The reason for this is that vector is an int*, but vector[nElementos - 1] is a regular int. Thus the declaration
int *pFinal = vector[nElementos - 1];
is trying to assign the integer value at the last index of vector to the pointer pFinal, hence the compiler error.
To fix this, you may want to do either
int *pFinal = &vector[nElementos - 1];
which makes pFinal point to the last element of vector, or
int *pFinal = vector + (nElementos - 1);
which accomplishes the same thing using pointer arithmetic.
That said, since you're working in C++, why not use the provided std::vector type and avoid working with pointers altogether?
Hope this helps!

vector is a pointer, but subscripting it as vector[nElementos-1] dereferences it to simply an int. What it looks like you want is instead
int *pComienzo = vector, *pFinal = &(vector[nElementos-1]);

An array access/subscript (i.e., a[i] where a is an array/pointer and i is an integer) is an expression with the type being the thing you have in the array.
Simply use the address-of operator & to store the address in the pointer:
int *pComienzo = vector, *pFinal = &vector[nElementos-1];

You forgot &. vector[nElementos-1] is the value, while you need an address for pFinal.
Either *pFinal = &(vector[nElementos-1]) or *pFinal = vector + nElementos-1.

Related

Expected primarly expression before ]? (C++)

error: expected primary-expression before ']' token
calcNumbers(myArr[], type);
^
No idea what that means. Main issue seems to be at 11 but i think i have more than that. Also how can improve code? Do i put pointers somewhere or something, should i structure it more somehow or would this be applicable in a job?
#include <iostream>
void calcNumbers(int arr[] ,int type);
int askNumbers();
int askType();
int main()
{
int type = askType();
int myArr = askNumbers();
calcNumbers(myArr[], type);
}
int askType()
{
int type_ = 0;
std::cout << "1 for addition. 2 For subtraction. 3 for multiplication. 4 for division." << std::endl;
std::cin >> type_;
return type_;
}
int askNumbers()
{
int arr[] = {};
std::cout << "Enter as many numbers you'd like. Type 0 to stop." << std::endl;
int i = 0;
do
{
std::cin >> arr[i];
i++;
}
while(arr[i] != 0);
return arr[];
}
void calcNumbers(int arr[] , int _type)
{
int arrSize = (int)( sizeof(arr));
int totalNumber = 0;
for(int i = 0; i < arrSize; i++)
{
if (_type == 1)
totalNumber += arr[i];
else if (_type == 2)
totalNumber -= arr[i];
else if (_type == 3)
totalNumber *= arr[i];
else if (_type == 4)
totalNumber /= arr[i];
}
std::cout << totalNumber << std::endl;
}
thanks in advance, i really cannot wrap my head around this wierd issue...
The error message tells you that an expression is expected at a certain point in your code:
calcNumbers(myArr[missing expression here ], type);
Why is that? Because operator[] takes an argument (traditionally an index), as in myArr[1]. No argument, no compile.
Note that this error occurs when you are using myArr. You have other places where [] is used in a declaration, and in those locations it is accepted as it is part of the type. If you have an array and you want to pass the entire array as a parameter, use just the variable name, as in calcNumbers(myArr, type);. (This would assume that myArr is an array, even though it is not in your code. You declare myArr as type int.)
Then again, your code has many problems with array usage (such as the lack of a bound on the index in askNumbers). You may want to find a good tutorial on array usage in C++. Or see if you can use std::vector after reading vector - C++ Reference or std::vector - cppreference.com.

Pointer to array in function in c++

I am a beginner to c++. Pointer is quite confusing to me. Especially on how to use it in functions and array. I tried to create a pointer to array in function and just output it. However it keeps giving me the address of the array instead of the value.
void testing(int* arr){
cout << arr << endl;
}
int main()
{
int my_arr[]{ 4,7,1 };
testing(my_arr);
string y;
getline(cin, y);
return 0;
}
I tried using testing(&my_arr); to output value but it give me errors:
argument of type "int (*)[3]" is incompatible with parameter of type
"int *
'void testing(int *)': cannot convert argument 1 from 'int (*)[3]' to 'int *'
Thanks a lot for any help!
To print the values in an array rather than the starting address, you need to use a loop.
#include <iostream>
#include <string>
// note extra param for length of array.
void testing(int* arr, int len){
for (int i = 0; i < len; ++i)
std::cout << arr[i] << " ";
std::cout << "\n";
}
int main()
{
int my_arr[]{ 4,7,1 };
testing(my_arr, 3);
return 0;
}
You can't pass testing(&my_arr) because &my_arr is of type int (*)[] as per the error message you received. That is not the same as int*.
for printing the arrays, you can either use the array index or pointers arithmetic. The test function could also be written as
void testing(int* arr, int len) {
for (int ctr = 0; ctr < len; ctr++) {
std::cout << *(arr + ctr) << std::endl;
}
}
int main()
{
int my_arr[]{ 4,7,1 };
testing(my_arr, 3);
return 0;
}
In testing() you are trying to use arr element without its index.
Here arr is the only base memory address of that memory. To get value from there you have to specify index.
void testing(int* arr, int len)
{
for(int i = 0; i < len; i++)
{
cout << arr[i] << endl;
}
}
In main() you can pass a length of an array.
int main()
{
int my_arr[]{ 4,7,1 };
testing(my_arr, sizeof(my_arr) / sizeof(int));
return 0;
}

add element to array of struct in C++ encountered "error no match for ‘operator=’"

My code was
#include <iostream>
#include <string>
using namespace std;
struct Numbers{
int a;
int b;
int c;
};
struct NumbersArray{
int size;
Numbers *numbers;
};
int main(){
NumbersArray numArr;
numArr.size = 10;
numArr.numbers = new Numbers[10];
for(int i = 0; i < 10; i++){
Numbers *num = new Numbers;
num->a = i * 3 + 0;
num->b = i * 3 + 1;
num->c = i * 3 + 2;
numArr.numbers[i] = num;
}
}
The basic idea is I create a struct called Numbers which contains 3 numbers and put it in a wrapper struct called NumbersArray.
And when I compile it with g++, I got error message
testArrayStruct.cc: In function ‘int main()’:
testArrayStruct.cc:23:27: error: no match for ‘operator=’ (operand types are ‘Numbers’ and ‘Numbers*’)
numArr.numbers[i] = num;
^
testArrayStruct.cc:23:27: note: candidate is:
testArrayStruct.cc:4:8: note: Numbers& Numbers::operator=(const Numbers&)
struct Numbers{
^
testArrayStruct.cc:4:8: note: no known conversion for argument 1 from ‘Numbers*’ to ‘const Numbers&’
Just ignore memory management here.
I cant figure it how to add elements to the array.
You are practising on the wrong things, and you will just
pick up bad habits this way. C++ thrive on value semantics,
focus on that:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct Numbers {
int a;
int b;
int c;
};
using NumbersArray = vector<Numbers>;
int main()
{
NumbersArray numArr;
numArr.resize(10);
for(int i = 0; i < 10; i++)
{
Numbers num;
num.a = i * 3 + 0;
num.b = i * 3 + 1;
num.c = i * 3 + 2;
numArr[i] = num;
}
}
It should be (ignoring your memory management as you asked):
numArr.numbers[i] = *num;
Instead of
numArr.numbers[i] = num;
since numArr.numbers[i] is of type Numbers while num is of type Numbers*.
EDIT:
The error actually tells you that there is no operator= to perform assignment of Numbers * to Numbers. So actually you could implement your own operator= which would perform such operation:
Numbers& operator=(Numbers& left, const Numbers * const right)
{
if (right != NULL) // or nullptr for C++11
{
left = *right;
}
return left;
}
With such implementation your original code would also compile.
One remark regarding the memory management. There is no real need to allocate new Numbers inside the for loop since you copy that content into the numArr.numbers anyway. So you could write it that way:
for(int i = 0; i < 10; i++){
numArr.numbers[i].a = i * 3 + 0;
numArr.numbers[i].b = i * 3 + 1;
numArr.numbers[i].c = i * 3 + 2;
}
how to add elements to the array
You can't.
When you said new Numbers[10] you created an array of ten default-initialized elements. An array can't resize itself after initialization.
It sounds like you should be using std::vector:
int main() {
std::vector<Numbers> numArr;
for(int i = 0; i < 10; i++) {
Numbers num;
num.a = i * 3 + 0;
num.b = i * 3 + 1;
num.c = i * 3 + 2;
numArr.push_back(num);
}
std::cout << "numArr contains " << numArr.size() << " elements." << std::endl;
}
Now you can add as many elements as you like and don't have to keep track of size etc. yourself. std::vector will resize itself when it needs to.
Try the following code. You are try to assign a pointer of an object to the object itself. The following one fixes it.
#include <iostream>
#include <string>
using namespace std;
struct Numbers{
int a;
int b;
int c;
};
struct NumbersArray{
int size;
Numbers **numbers;
};
int main(){
NumbersArray numArr;
numArr.size = 10;
numArr.numbers = new Numbers* [10];
for(int i = 0; i < 10; i++){
Numbers *num = new Numbers;
num->a = i * 3 + 0;
num->b = i * 3 + 1;
num->c = i * 3 + 2;
numArr.numbers[i] = num;
}
}
This is the important part of your error message:
error: no match for ‘operator=’ (operand types are ‘Numbers’ and ‘Numbers*’)
You are trying to assign a pointer to Numbers into a Numbers value. The rest of the error message is not helpful.
Assuming you don't want to change the NumbersArray class like all the other answers are suggesting, your inner loop should look like this:
for(int i = 0; i < 10; i++){
Numbers num;
num.a = i * 3 + 0;
num.b = i * 3 + 1;
num.c = i * 3 + 2;
numArr.numbers[i] = num;
}
Read about values and pointers in C++.

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++ qsort 2D array

I am still getting lldb error, because i am probably accessing memory, that i shouldn't.
It looks like i am doing something wrong when manipulating with parameters in io_seg_sort, because before calling qsort, it is still ok.
#define IO_SEG_IMAX (IO_SEG - 1)
static int io_seg_sort (const void * seg1, const void * seg2) {
int * _seg1 = (int *)seg1;
int * _seg2 = (int *)seg2;
cout << _seg1[1] <<endl; // this gives some random values and not what i am expecting
if (_seg1[1] > _seg2[1]) {
return 1;
}
else if (_seg1[1] < _seg2[1]) {
return -1;
}
else {
return 0;
}
}
int **temp = new int *[IO_SEG];
for (int i = 0; i <= IO_SEG_IMAX; i++) {
temp[i] = new int[2];
memcpy(temp[i], inputs[i], sizeof(int) * 2);
}
qsort(temp, IO_SEG, sizeof(int *) , io_seg_sort);
EDIT1: the problem is i am getting some random values in io_seg_sort when calling cout instead of what i am expecting. inputs[i] is class member int inputs[IO_SEG][2];
You're putting IO_SEG_MAX + 1 items into an array that's IO_SEG long.
for (int i = 0; i <= IO_SEG_IMAX; i++) {
temp[i] = new int[2];
memcpy(temp[i], inputs[i], sizeof(int) * 2);
}
That should be:
for (int i = 0; i < IO_SEG; i++) {
temp[i] = new int[2];
memcpy(temp[i], inputs[i], sizeof(int) * 2);
}
But if you really intend to do this in C++, you should look into std::vector and std::sort.
The primary reason your code prints garbage is that you have mismatched levels of indirection inside the comparison function. Your temp array that you pass to qsort consists of pointers to two-element arrays. That means that inside the comparison function you actually receive pointers to pointers to int. I.e. this is already incorrect
static int io_seg_sort (const void * seg1, const void * seg2) {
int * _seg1 = (int *)seg1;
int * _seg2 = (int *)seg2;
cout << _seg1[1] <<endl;
You have to do something like
static int io_seg_sort (const void * seg1, const void * seg2) {
const int * _seg1 = *(const int *const *) seg1;
const int * _seg2 = *(const int *const *) seg2;
to get access to your arrays through _seg1 and _seg2 as you do it in the body of io_seg_sort (I also added some const qualifiers, although they are not required for the code to work.)