c++ function with pointers as argument problem - c++

I am using fftw for a fourier transform in c++. There is the standard data type fftw_complex, which is basically a double[2]. I want to make an array of fftw_complex. I do this with
typedef fftw_complex fftw_complex_16[65536];
I set everything to zero in the array. Then I have another function which should check if an fftw_complex_16 is empty.
bool is_empty_fftw_complex_16(fftw_complex_16 *thecomplex){
std::cout<<"Test\n"<<::vowels["a:"][0][0]<<std::endl;
for (unsigned long i=0; i<65536; i++){
if(thecomplex[i][0] != 0 || thecomplex[i][1] != 0){
std::cout<<"Huch!"<<i<<std::endl;
std::cout<<thecomplex[i][0]<<" -- "<<thecomplex[i][1]<<std::endl;
std::cout<<*thecomplex[i][0]<<" -- "<<*thecomplex[i][1]<<std::endl;
return 1;
}
}
return 0;
}
Forget about the couts, they are only for debugging. The only thing the function should do is return true if the array the pointer argument points to is empty and false otherwise. It does not work. The function says the array is not empty when it is! Please help, what am I doing wrong?

The problem seems to be this
bool is_empty_fftw_complex_16(fftw_complex_16 *thecomplex){
which from your description should really be this
bool is_empty_fftw_complex_16(fftw_complex *thecomplex){
but it's hard to be completely sure because you didn't post the code which sets up this array and calls this function, which unfortunately is a crucial thing to miss out.
Something like this would be the correct way to call the function
fftw_complex_16 array;
...
is_empty_fftw_complex_16(array);
I'm guessing that you combined the incorrect declaration above with this incorrect call.
fftw_complex_16 array;
...
is_empty_fftw_complex_16(&array);
This compiles but doesn't do what you wanted.

Related

How to call a specific function from an array of functions?

I'm working on building a watch based on the Arduino/ATMega. The primary goal for now is to switch between "modes” (different functions) by pressing a button on the side. Initially, I had a long if statement like this:
if (counter == 0)
mode1();
enter code
else if (counter == 1)
mode2();
.... Repeat....
But that seems inefficient. So, I tried to make an array of the functions without actually calling them, and then call the indexed function later. The code segment is as follows (Apologies for the mess, it’s very much a WIP)
int Modes[3] = {showTime,flashlight,antiAnxiety} //these are all void functions that are defined earlier.
int scroller(){
int counter = 0;
int timeLeft = millis()+5000;
while (timer <= millis()){
...more code...
}
Modes[counter]();
}
However, when I try to compile that, I get an error:
Error: expression cannot be used as a function.
That logic works in Python, so I’m assuming there’s a concept I don’t know that gets abstracted away in higher-level languages. I’m quite willing to learn it, I just need to know what it is.
The type is wrong - instead of int you need void (*)() as type (because you have an array of void someFunction() function pointers, not an array of integers - and while the former can be converted to the latter in a way, as memory address, you cannot call an integer).
void (*Modes[3])() = {showTime, flashlight, antiAnxiety};
This code becomes easier to understand with a type definition:
typedef void (*func_type)();
func_type Modes[3] = {showTime, flashlight, antiAnxiety};

why "return 0" works for returning a pointer in function, but not works for reference?

edit on Feb 25: changed my question, and adding some describes to my question.
======================some complains===========================
To those people who down-vote my question:
This is my first question on stack-overflow.
about the question: this question was emerged from my thought. in my case, I thought the return 0 actually did something for my
program, and it absolutely did. The only thing could misunderstand
people is probably I gave a question that I think it works like that
way but it didn't.
about my attitude. Maybe you guys here are expert in C++ and you might think my question is stupid. However, as a non-English-native speaker, this question is took me 4 hours to think and do the test, 2 hours for searching on google but also took me at least half hour to post. As a self-taught newbie I already tried my best to make the question as best as I could.
Thus, please at least leave a comment to let me know what I could improved about the way I submit my question, when you do the downvote. Do not just make a simple click. Your click is just like a new question to make me consider: "am i did something wrong?" "how could I solve it?" It is going to force me to reconsider what I’ve done; but just like the normal questions, It would be help if someone could give some tips.
As a newbie, I won't stop to raise questions; so I think point out my problems will help me to improve my ability to raise high quality questions, and you will benefit also because you might see some good questions in future.
At last, thanks again for this place; I got a lot answers from here; And also thanks for those people who helped me to solved my problem.
=======================question line======================
This function I intend to get an array argument by using "using alias form", and trying to return the array itself back to the calling function. I tried to use pointer and reference both for this function.
here is what I learned from C++ primer:
using arrT = int[10];
arrT* func(int i);
This code is suppose to define a function that would return a pointer that point to a array with ten ints; I understand this, but I didn't get a example from book.
and here are my tries:
using pointer, trying to return the pointer directly, but error.
arrT* return_p(arrT arr){
for(int i = 0; i < 10; ++i){
*(arr+i) *= 2;
}
return arr;//error, can't convert int* to int (*)[10]
}
i know because here arr is converted and lost the array's dimension. However, I just found a way that works for me:
arrT* return_p(arrT arr){
for(int i = 0; i < 10; ++i){
*(arr+i) *= 2;
}
return 0; // return 0 is return pointer arr that point the first element of array arr.
}
I just wondering how did the return 0 work here? And I do have another result here if I use reference instead of using pointer:
arrT& return_r(arrT &arr){
for(auto &i : arr){
i *= 2;
}
return arr; // works, returned the reference to array named arr
}
but return 0 is not working for the reference version.
arrT& return_r(arrT &arr){
for(auto &i : arr){
i *= 2;
}
return 0; // error, using an int rvalue to initialize a non_const that has type int(&)[10];
}
I hope I told my question clearly. thanks for your help!
The literal 0 is a "null pointer constant", and it can be used to initialize a value of any pointer type (object pointer, function pointer, member pointer or void pointer). The result of this initialization is the null pointer value of that type.
There is no concept corresponding to that of "null pointer" for references: references are always bound to objects or functions. For pointers the "null" value is in some way a distinguished value that says "not the address of anything". And by contrast, a reference is not allowed to not be bound to anything. That's why your last example is ill-formed.
Incidentally, you can return the address of an array if you pass the array as a reference:
arrT * f(arrT & a) { return &a; }
What's confusing about array types is that arrays cannot be passed to or returned from functions by value, but the corresponding syntax is allowed -- it is allowed, but means something different: f(arrT x) actually means the same as f(int * x) in your case.
In more technical terms, arrays can only be passed and returnd as and glvalues, but not as prvalues.

How to overcome null pointer initialisation error? (C/C++)

I'm having a hard time figuring out why the initialisation at NULL of one pointer is bugging my program.
In order to not receive a compilation error, almost all the pointers in my code need to be initialise as nullptr like usual. Problem is, when I tried to use them afterwards, I get a whole bunch of errors telling me the null pointer is invalid. To overcome this error, the buggy pointers are now declare as an array. This way all my problems with this initialisation are gone. Everything seems to work fine until I realise one of my conditional branch was always returning false.
The full code is a bit too long and some parts use french words, so let's just paste what interest us...
struct Numero {
int num;
char client[50];
Message *listeMessage = nullptr;
Numero *suivant = nullptr;
int nbmsg = 0;
};
char buff_char[50];
number = new Numero;
file >> number->client; // getting the right char client[50] from the file
if (number->client == buff_char)
break;
I also tried if(*number->client == *buff_char) without success. I'm now thinking that the problem is probably the array of char, but because of my previous problem I can't really change that so I'm hoping somebody can figure out what's going on here.
Note: Don't suggest anything related to strings, I can't use them because it's part of the challenge here to practice with pointers.
number->client == buff_char
Both of these are arrays, which decay into pointers. They are two different arrays with two different addresses, so this will always return false.
*number->client == *buff_char
This would compare the first element in each array, which is also not what you want.
You can use a standard library function like strcmp.
If you can't use the standard library, loop over each array until one has a different element than the other (not equal), they both have '\0' (equal), or they both reach 50 (equal).
In If do a comparison instead of assignment
if (number->client == buff_char)
In C++ = is the assignment operator. You want == for equality. What your if statement does right now is sets client equal to buff_char and then evaluates based on the newly assigned value of client.

Default value of dynamic bool array in C++ [duplicate]

This question already has answers here:
Does new[] call default constructor in C++?
(4 answers)
Closed 8 years ago.
I need to create a bool array with an unknown length passed by parameter. So, I have the following code:
void foo (int size) {
bool *boolArray = new bool[size];
for (int i = 0; i < size; i++) {
if (!boolArray[i]) {
cout << boolArray[i];
}
}
}
I thought that a boolean array was initializing with false values...
Then, if I run that code in Eclipse (on Ubuntu), it works fine for me, the function prints all the values because !boolArray[i] return true (but the values are not false values, they are garbage values). If I run it in Visual Studio, the values are garbage values too, but the function does not print any value (because !boolArray[i] returns false). Why the array values are not false values by default?!? And why !boolArray[i] returns false in Visual Studio but it returns true in Eclipse?!?
I read this question: Set default value of dynamic array, so if I change the code like the following, it works fine for me too (in Eclipse and in Visual Studio)! But I have no idea why.
void foo (int size) {
bool *boolArray = new bool[size]();
for (int i = 0; i < size; i++) {
if (!boolArray[i]) {
cout << boolArray[i];
}
}
}
Sorry for my bad English!
Thanks in advance!
Adding the () for a POD instantiation, invokes value initialization in C++03 and later. In C++98 it invoked default initialization. But both reduce to zero initialization for POD types, and for booleans zero is false.
E.g., if S is a POD struct, and you have a variable
S o;
then you can zero it by doing
o = S();
No need for unsafe and ugly memset.
By the way, std::vector<bool> is a higher level alternative to your raw array of bool, but due to what's now seen as premature optimization it has a bit odd behavior: it supports an implementation with each boolean value represented by a single bit, and so dereferencing an iterator doesn't give you a reference to a bool as one might expect from general std::vector. So a better alternative is e.g. std::vector<My_bool_enum>, with My_bool_enum properly defined. Or just std::vector<char>. ;-)
Regarding
“And why !boolArray[i] returns false in Visual Studio but it returns true in Eclipse?!?”
It's just that Visual C++ chooses efficiency, not initializing where it doesn't have to, while the compiler used in Eclipse (presumably g++) does initialize even though it doesn't have to and isn't requested to do.
I prefer the Visual C++ behavior here for two reasons:
A main idea in C++ is that you don't pay for what you don't use, and the Visual C++ behavior here is in line with that idea.
Zero-initialization can easily give users the false impression that their code works, when in fact it's not portable.

warning: uninitialized variable //But I have initialized ! C++ Compiler bug?

Iam trying to compile this program but i get warning and when i run vc++ 2010 debugger pops up : (
Here is my code :
#include <iostream>
using namespace std;
int num;
int min(int mas[])
{
int i,minn,index; /* But I have declared them : (((( */
for(i=0;i<num;i++)
{
if(mas[i]!=0)minn=mas[i];
break;
}
if(i==num) return 0;
for(i=0;i<num;i++)
if(mas[i]!=0 && minn>mas[i])
{
minn=mas[i];
index=i;
}
mas[index]=0;
return minn;
}
int main()
{
cin>>num;
int *array=new int[num]; int tmp;
tmp=min(array);
}
and Here is a compiler log :
prog.cpp: In function ‘int min(int*)’:
prog.cpp:6: warning: ‘index’ may be used uninitialized in this function
prog.cpp:6: warning: ‘minn’ may be used uninitialized in this function
What i am doing wrong ? or its is compiler bug ? :)
Thank you :)
You have declared them, but not initialized them. Simply write int minn = 0, index = 0; to avoid the warning. If you don't initialize a variable, its default value is whatever was at that location in memory already; usually garbage.
The thing is, if num is negative, then neither of the for loops in your min() function will execute, and so minn and index will not have been assigned values. The if(i == num) test also won't break out of the function and prevent this from happening. So the last two lines of the function will have completely undefined results.
Sometimes there really isn't a path for the variables to be used uninitialized, though; sometimes the compiler just isn't quite smart enough to figure out all the subtleties. Just give them an initial value to avoid the warning.
Declaration != initialization. When you declare them the variables have random values. Just initialize them to sensible values like -1 for index and minn to a INT_MAX.
But you haven't initialized them : ))))
EX: int i,minn=0,index=0; Imagine that you pass num that equals 0, at the end you would be returning uninitialized value of minn and just before that you would set mas[unknown_number]=0; which will probably cause your app to crash since you will be referencing memory that is most likely beyond your scope. You should do a check in the beggining like if(num<1)return -1;
Suppose the entire array you pass in is 0. Both loops short-circuit and never execute, both minn and index are uninitialized.
Now if this happens, what should be happening? Set the variables to the values that accomplish just that.
As you say in your comment, yes, you have declared your variables, but you haven't initialized them. Initializing a variable means giving it a value. So in this case, you have told the compiler that you want to create three integers, but you haven't told it what values you want to store in those integers. That would be ok if, for every possible path through your function, index and minn were guaranteed to be given a value, but the problem here is that there is a path through your function where minn and index will never be initialized. First of all, here:
for(i=0;i<num;i++)
{
if(mas[i]!=0)minn=mas[i];
break;
}
If you have an array of zeros, then minn is never initialized to a value.
Then further down:
for(i=0;i<num;i++)
if(mas[i]!=0 && minn>mas[i])
{
minn=mas[i];
index=i;
}
first of all, if you had an array of zeros, well what is the value in minn? There is no value. You are asking the compiler to compare mas[i] to a number which doesn't exist. Furthermore, what if mas[i] is always equal to zero? Well now you don't initialize minn or index. Yet at the end of the function, you are attempting to use the value of index to get an integer from the array amd then you return minn (which still equals nothing).
That's the problem you're getting from the compiler. It can see this potential outcome and is warning you that your function can be broken due to these integers never getting a value. To fix it, do what the other lads have suggested and let index and minn equal zero at the start.