C output differ with the same code - c++

#include <stdio.h>
#include <stdlib.h>
int main() {
int* a[10];
int* p = a;
int i = 0;
for (p = &a[0], i = 0; p < &a[10]; p++, i++)
{
*p = i;
}
for (int i = 0; i < 10; i++)
{
printf("%d\n", a[i]);
}
}
the output on GCC using eclipse:
0
2
4
6
8
10
12
14
16
18
the output using visual studio:
0
1
2
3
4
5
6
7
8
9
why ?

% gcc error.c -Wall -Wextra
error.c: In function ‘main’:
error.c:7:14: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
int* p = a;
^
error.c:9:12: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
for (p = &a[0], i = 0; p < &a[10]; p++, i++)
^
error.c:9:30: warning: comparison of distinct pointer types lacks a cast
for (p = &a[0], i = 0; p < &a[10]; p++, i++)
^
error.c:15:18: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat=]
printf("%d\n", a[i]);
^
Hint:
int a[10]; // notice the lack of star here.

a is declared as an array of 10 pointers to int. a in int* p = a; will decay to int **, but p is of type int *. Compiler will raise a warning about incompatible pointer assignment. You need to change the declaration
int* a[10];
to
int a[10];
This program invokes undefined behavior, so strange things can happen.

Related

Error "argument type f "int" is incompatable with parameter of type "int*" and 'int assignVal(int[])': cannot convert argument 1 from 'int' to 'int[]'

For a class assignment I have to fill multiple array types with random numbers. Here is the code I have but keep getting the above error message:
Error "argument type f "int" is incompatable with parameter of type "int*"
and 'int assignVal(int[])': cannot convert argument 1 from 'int' to 'int[]'
Any help is greatly appreciated, here the code:
#include <iostream>
using namespace std;
const int len = 5;
int assignVal(int array[len]);
int main()
{
double arr1[len];
int arr2[len];
int arr3[len];
assignVal(arr2[len]);
}
int assignVal(int array[len])
{
for (int i = 0; i <= len; i++)
{
array[i] = rand() % 10;
}
}
The problem is your call:
assignVal(arr2[len]);
THis does not do what you think: it calls the function with the len-th element of arr2 array. So you try to pass an int element instead of the array.
Try:
assignVal(arr2);

passing in int* for int[][] C/C++

Suppose I have the following code
#include <stdio.h>
#include <stdlib.h>
int foo(int bar[3][3]){
return bar[1][1];
}
int main(){
int* bar = (int*) malloc(9 * sizeof(int));
for(int i = 0; i < 9; i++){
bar[i] = i;
}
int test = foo(bar);
printf("%d\n", test);
}
Compiling this with C gives a warning
warning: incompatible pointer types passing 'int *' to parameter of type 'int (*)[3]' [-Wincompatible-pointer-types]
int test = foo(bar);
But still outputs the expected result of 4 (Although I imagine the warning is a sign of UB)
Compiling with g++ gives an error
error: no matching function for call to 'foo'
int test = foo(bar);
note: candidate function not viable: no known conversion from 'int *' to 'int (*)[3]' for 1st argument
int foo(int bar[3][3]){
I cannot change the function signature of bar but would like to just pass in a simple pointer to the array. What is the simplest typecast/change of code that would make this compile with no UB with g++. This is for code that I am generating with a Python script while looking at the function signature of bar so the simpler the solution the better. (This is just an example)
Quick and dirty fix:
foo(reinterpret_cast<int(*)[3]>(bar)); // C++ only
foo((int(*)[3])bar); // C and C++
Replaces the implicit cast present in C language with an explicit one to let the C++ compiler know you are intending to circumvent the type-system.
Without dynamic memory allocation:
int main(void) {
int bar[3][3];
for (int i=0; i<9; ++i) {
bar[i / 3][i % 3] = i;
}
printf("%d\n", foo(bar));
}
With: (C)
int main(void) {
int (*bar)[3] = malloc(3 * sizeof(int[3]));
for (int i=0; i<9; ++i) {
bar[i / 3][i % 3] = i;
}
printf("%d\n", foo(bar));
}
What is the simplest typecast/change of code that would make this compile with no UB with g++
int main(){
int bar[3][3];
for(int i = 0; i < 9; i++){
bar[i / 3][i % 3] = i;
}
int test = foo(bar);
printf("%d\n", test);
}
Works in both C++ and C

Error: invalid conversion from int to int(*)[4] in function calls

I'm working on a homework project where I have to do a modified preorder traversal through an array-based tree and I need to pass the array to the function in order to use it but I keep getting an error in the function saying that it's an invalid conversion from int to int(*)[4] and I can't seem to figure out why.
Here's a copy of my code:
#include <iostream>
#include <fstream>
char code[10];
void preOrder(int tree[][4], int index, int treeDepth)
{
int tempIndex;
if(tree[index][2] == -1 && tree[index][3] == -1)
{
std::cout << char(tree[index][1]) << ": ";
for(int i = 0; i < treeDepth; i++)
std::cout << code[i];
std::cout << "\n"
}
else
{
for(int i = 0; i < 2; i++)
{
code[treeDepth] = 0;
tempIndex = tree[index][2];
preOrder(tree[index][2], tempIndex, treeDepth + 1);
code[treeDepth] = 1;
tempIndex = tree[index][2];
preOrder(tree[index][3], tempIndex, treeDepth + 1);
}
}
return;
}
int main()
{
int numNodes = 0, i = 0, j = 0;
int root = 0, treeDepth = 0;
int numcols = 4;
std::fstream inFile;
inFile.open("tree.dat");
inFile >> root;
inFile >> numNodes;
int huffmanTree[numNodes][numCols];
for(i = 0; i < numNodes; i++)
for(j = 0; j < numCols; j++)
inFile >> huffmanTree[i][j];
preOrder(huffmanTree, root, treeDepth);
inFile.close();
return 0;
}
Any help would be greatly appreciated.
And also I can't use pointers and I can also declare huffmanTree as global but couldn't figure out how to get that to work either. And also sorry for the way everything it placed. This is my first time posting.
The errors are:
ola.cpp: In function ‘void preOrder(int (*)[4], int, int)’:
ola.cpp:28:53: error: invalid conversion from ‘int’ to ‘int (*)[4]’ [-fpermissive]
ola.cpp:10:6: error: initializing argument 1 of ‘void preOrder(int (*)[4], int, int)’ [-fpermissive]
ola.cpp:31:53: error: invalid conversion from ‘int’ to ‘int (*)[4]’ [-fpermissive]
ola.cpp:10:6: error: initializing argument 1 of ‘void preOrder(int (*)[4], int, int)’ [-fpermissive]
ola.cpp: In function ‘int main()’:
ola.cpp:67:39: error: cannot convert ‘int (*)[(((sizetype)(((ssizetype)numCols) + -1)) + 1)]’ to ‘int (*)[4]’ for argument ‘1’ to ‘void preOrder(int (*)[4], int, int)’
Regarding your error on line 67: in Standard C++ this is not permitted:
int huffmanTree[numNodes][numCols];
Only constant expressions may be used as array dimensions.
Some compilers implement a non-standard extension to allow this sort of array, but not very well: it appears that, for your compiler, this extension doesn't extend to passing the array to a function that expects an array of fixed width.
Possibly it would fix your problem to use const int numcols = 4; instead.
The errors on line 28 and 31 are due to calling preOrder(tree[index][2] . Your first argument is an int but the function expects pointer to array. If you're trying to create a slice of the array starting at some particular row and column - that actually isn't possible. You'd have to pass tree, index, 2, tempIndex, treeDepth + 1 instead, adding 2 more parameters to your function which indicate the starting point; and modifying the function logic accordingly.

invalid conversion from 'int' to int* [-fpermissive]

Previously I had this implemented and it worked:
int *train_X = (int *)mxGetData(IN_a);// pointer to 6th argument matrix train_X
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < 6; j++)
{
cout << train_X[6 * i + j] << endl;
}
}
int sizeTrain_X1 = mxGetM(IN_a);
int sizeTrain_X2 = mxGetN(IN_a);
I could even manage to check if i get the correct sizes with the following and it was all good.
cout <<"Training input NumOfCollum:\n"<< sizeTrain_X1 << endl;
cout << "Training input NumOfRows:\n"<<sizeTrain_X2 << endl;
but then when trying my entire program with the following initialization i get a compilation error:
for (int epoch = 0; epoch<training_epochs; epoch++)
{
for (int i = 0; i<train_S; i++)
{
rbm.contrastive_divergence(train_X[i], learning_rate, k);
}
}
Here is the error message:
RBM.cpp: In function ‘void mexFunction(int, mxArray**, int, const
mxArray**)’:
RBM.cpp:570:64: error: invalid conversion from ‘int’ to ‘int*’ [-fpermissive]
RBM.cpp:81:6: error: initializing argument 1 of ‘void RBM::contrastive_divergence(int*, double, int)’ [-fpermissive]
RBM.cpp:615:32: error: invalid types ‘int[int]’ for array subscript
train_X is an int*. When you do train_X[i] you now get an int. contrastive_divergence() though wants an int*. Since you cannot convert an int to an int* you are getting the subsequent error. You either need to pass the address of train_X[i] as &train_X[i] or just pass train_X

Why can the address of an array variable can not be assigned to a pointer? And what are 'Wfatal-errors'?

I tried the below-pasted code and got an error:
cannot convert int (*)[6] to int* in assignment
compilation terminated due to -Wfatal-errors.
#include <stdio.h>
int my_array[] = {1,23,17,4,-5,100};
int *ptr;
int main(void)
{
int i;
ptr = &my_array; /* point our pointer to the first
element of the array */
printf("\n");
for (i = 0; i < 6; i++)
{
printf("my_array[%d] = %d ",i,my_array[i]); /*<-- A */
printf("ptr + %d = %d\n",i, *(ptr + i)); /*<-- B */
}
return 0;
}
ptr = &my_array;
The type of &my_array is int (*)[6] while the type of ptr is int*. They're incompatible types.
What you should be doing is this:
ptr = my_array;
Now the type my_array is int[6] which decays into int* in the above context. So it works.
You have to use:
ptr = my_array;
Which is equivalent to:
ptr = &my_array[0];
An array is convertible to a pointer. What you meant to do is:
ptr = my_array;
All you need to do here is:
ptr = my_array;
There's no need to use the & operator.