"may be used uninitialized in this function [-Wmaybe-uninitialized]" - c++

I would like to ask a question that make me confuse. I am trying so scan string and covert that into real number. Using that number to calculate value. Here is my code:
string input_file_name1 = "shen_test_38_30_60__78_26_38_b_100_ch1-533.0-mhz-8000.0-ksps-2016-06-20-17.24.19-utc.dat";
string input_file_name2 = "shen_test_38_30_60__78_26_38_b_100_ch2-533.0-mhz-8000.0-ksps-2016-06-20-17.24.19-utc.dat";
std::ifstream input1(input_file_name1.c_str() , std::ios::binary | std::ios::in);
std::ifstream input2(input_file_name2.c_str() , std::ios::binary | std::ios::in);
split(input_file_name1, '-', v);
for(unsigned i=1; i < v.size(); i++)
{
if(v[i] == "mhz"){
f_0 = atoi(v[i-1].c_str())*1e6;
}
if(v[i] == "ksps"){
f_s = atoi(v[i-1].c_str()) * 1e3;// f_s = 8e6;
}
}
double nblocks; //f_s = 8e6;
nblocks = floor(10 / (262144 / f_s));
when I compile I got this message:
" warning: ‘f_s’ may be used uninitialized in this function [-Wmaybe-uninitialized] nblocks = (10 / (nsamps / f_s));"
Do you have any ideal to help me fix this problem?
Thank you so much.

That means that if v[i] is neither "mhz" nor "ksps", then the code that assigns something to f_s is never executed and therefore leaving f_s uninitialized.
You can prevent this warning for example like this:
for(unsigned i=1; i < v.size(); i++)
{
if(v[i] == "mhz"){
f_0 = atoi(v[i-1].c_str())*1e6;
}
else if(v[i] == "ksps"){
f_s = atoi(v[i-1].c_str()) * 1e3;// f_s = 8e6;
}
else
{
// v[i] is none of the expected values
f_s = -1;
... take more action
}
}

The issue here is that if(v[i] == "ksps") may never be true. If it is not then f_s never gets a value set to it. What you can do is default initialize f_s with some value. Then you at least know the variable has some known state.
Do note that if you have not intialized f_0 you will have the same issue with it.

Related

stoi() terminate after throwing and instance of 'std::invalid argument in c++-- What am I doing wrong?

Fairly new to coding. Trying some of the easy projects at LeetCode, and failing... Ha! I am trying to take an integer and convert it to a string so I can reverse it, then re-convert the reversed string back into a integer.
This code is throwing the "terminate after throwing and instance of 'std::invalid argument' what(): stoi" error. I've spent an hour searching google and other questions here on SO, but can't figure out why it's not working.
bool isPalindrome(int x) {
std::string backwards ="";
std::string NumString = std::to_string(x);
for (int i = NumString.size(); i >= 0 ; i--) {
backwards += NumString[i];
}
int check = std::stoi(backwards);
if (check == x) {
return true;
}
else {
return false;
}
}
EDIT: I think I figured it out. It was adding the null character to the end of the string upon first conversion, then adding it to the beginning of the string when I reversed it. Spaces can't be converted to integers.
So... I changed this line and it works:
for (int i = NumString.size() - 1; i >= 0 ; i--)
you can also reverse number without using string.
bool isPalindrome(int x) {
long long rev = 0;
int cur = x;
while( cur > 0) {
rev *= 10;
rev += cur % 10;
cur /=10;
}
return rev == x;
}
Its simpler than your answer that you edited in. YOu have
for (int i = NumString.size(); i >= 0 ; i--) {
backwards += NumString[i];
}
Imagine that Numstring has length 3 (no matter what spaces, digits,....)
So now you are efectively doing
for (int i = 3; i >= 0 ; i--) {
backwards += NumString[i];
}
So first loop goes
backwards += NumString[3];
well the indexes of things in an array of length 3 in c++ are 0,1,2. YOu are going one off the end
This is why you see loops doing
for(int i = 0; i < len; i++){}
Note the i < len not i <= len

Trying to avoid if-else statement inside for-loop but the code seems to have some errors

This snippet works just fine.
for (int i = 0; i < 1; i++) // for some other purpose
{
// some other code
double** angle = new double* [10]; // for a 2D matrix
for (int j = 0; j < 10; j++)
{
angle[j] = new double [3];
if (j == 0)
angle[j][0] = 2; // focused on the first column for now
else
angle[j][0] = angle[j-1][0]+3;
std::cout << angle[j][0] << std::endl;
}
for (int i = 0; i < 10; i++)
delete[] angle[i];
delete[] angle;
}
I am trying to not use conditional statement inside the loop. If I replace that with the following line, the code stops working. Please help me understand it.
angle[j][0] = (j == 0) * 2 + (j != 0) * (angle[j-1][0] + 3);
Using g++ -std=c++11 -o out main.cpp; ./out on Ubuntu 16.04 LTS
You're trying to use the ternary operator, but the syntax is wrong.
Do this:
angle[j][0] = (j == 0) ? 2 : (angle[j-1][0] + 3);
The line
angle[j][0] = (j == 0) * 2 + (j != 0) * (angle[j-1][0] + 3);
does not work since you access angle[-1] when j is 0. That is a reason for undefined behavior.
Looking at your comment to the other answer, you are apparently looking for using the conditional operator.
angle[j][0] = (j == 0) ? 2 : (angle[j-1][0] + 3);
As Sahu said, the problem with your combined line is that you take angle[j-1][0] with j==0, which is undefined behavior. This means that combining both if and else parts into a single non-branching statement is not really possible.
Secondly, these two code snippets look different (with the ternary/conditional operator producing fewer lines of C++ code):
if (x == 1)
A = 7;
else
A = 13;
versus
A = (x == 1) ? 7 : 13;
But they compile to exactly the same machine code.
So, how do we fix your problem of not wanting to branch in every single loop iteration?
Since the test/branch variable (j) is also the loop variable and the test is for j == 0, which is also the starting condition, you can do something like this:
double** angle = new double* [10]; // for a 2D matrix
angle[0] = new double[3]; // Prepare the first element
angle[0][0] = 2;
for (int j = 1; j < 10; j++) // Fill out the rest
{
angle[j] = new double[3];
angle[j][0] = angle[j - 1][0] + 3;
std::cout << angle[j][0] << std::endl;
}
Where the setup for the first element is moved out of the loop, after which the loop can be started at j=1 and only have the else branch in the loop body (with no test, of course).
However, given that branch predictors in modern CPUs are pretty awesome, and your loop hits the if-branch exactly once; on the first loop-iteration, and the else-branch on every following one, I doubt that you will see much difference in the execution times for the two versions. So, I would simply recommend that you pick the version that you find most easy to read and understand.

Wrong array variable getting changed

In the following function I clearly change the variable rightArray through the statement: rightArray[i] = dataValues[i];
However the behaviour I'm getting from the function is that the variable leftArray is changing in place of rightArray
//Returns the interquartile range
float StatisticalAnalyser::getInterquartileRange()
{
float interquartileRange = 0;
int numberOfDatums = dataFile.findNumberOfDatums();
float numberOfDatumsFloat = dataFile.findNumberOfDatums();
float dataValues[dataFile.findNumberOfDatums()];
dataFile.initialiseArrayToFileData(dataValues);
//If even number of datums
if (numberOfDatums % 2 == 0)
{
//Arrays for for each side of the median
int arraySize = numberOfDatumsFloat/2;
float leftArray[numberOfDatums/2];
float rightArray[numberOfDatums/2];
//Initialise arrays for each side of the median
for (int i = 0; i < numberOfDatums; i++)
{
if (i < numberOfDatums/2)
{
leftArray[i] = dataValues[i];
}
if (i >= numberOfDatums/2)
{
//leftArray SOMEHOW GETS CHANGED INSTEAD OF RIGHT ARRAY
rightArray[i] = dataValues[i];
leftArray gets changed instead of rightArray here: rightArray[i] = dataValues[i];
}
}
}
if (numberOfDatums % 2 == 0.5)
{
//Not relevant, isn't triggered when problem occurs
}
return interquartileRange;
}
I am running Xcode 10.1, and want to know how to fix this error so that rightArray is changed by the function instead of leftArray.
Having
float leftArray[numberOfDatums/2];
float rightArray[numberOfDatums/2];
in
if (i >= numberOfDatums/2)
{
//leftArray SOMEHOW GETS CHANGED INSTEAD OF RIGHT ARRAY
rightArray[i] = dataValues[i];
you go out of rightArray and randomly write in leftArray (of course this is an undefined behavior)
must be
if (i >= numberOfDatums/2)
{
rightArray[i - numberOfDatums/2] = dataValues[i];
Furthermore, to have
if (i < numberOfDatums/2)
{
...
}
if (i >= numberOfDatums/2)
with i unchanged is useless, the second if can be an else, but it is also better to do two for to not have to do numberOfDatums/2 all the times just to decide which array to use.

C++ memory: deleting an unused array of bool can change the result from right to wrong

I am trying to solve Project Euler Problem 88, and I did it without too much effort; however, I find that some seemingly irrelevant code in my program is affecting the result. Here's my complete code (it's not short, but I cannot locate the error. I believe it would be obvious to more experienced eyes, so please read my description first):
#include <iostream>
#include <set>
using namespace std;
bool m[24001][12001];
bool p[24001]; // <------------ deleting this line will cause error in result!
long long answer[12001];
int main() {
long long i;
long long j;
long long l;
set<long long> all;
long long s = 0;
for (i = 0; i <= 24000; i++) {
for (j = 0; j <= 12000; j++) {
m[i][j] = false;
}
}
m[1][1] = true;
for (i = 2; i <= 24000; i++) {
m[i][1] = true;
for (j = 2; (j <= i) && (i * j <=24000); j++) {
for (l = 1; l <= i; l++) {
if (m[i][l]) {
m[i * j][l + 1 + (i * j) - i - j] = true;
}
}
}
}
for (i = 0; i <= 24000; i++) {
for (j = 0; j <= 12000; j++) {
if (m[i][j] && (answer[j] == 0)) {
answer[j] = i;
}
}
}
for (i = 2; i <= 12000; i++) {
cout << answer[i] << endl;
all.insert(answer[i]);
}
cout << all.size() << endl;
for (set<long long>::iterator it = all.begin(); it != all.end(); it++) {
//cout << *it << endl;
s += *it;
}
cout << s << endl;
}
With the "useless" bool array, all the answers are right, between 0 and 24000; but without it, some answers in the middle got corrupted and become very large numbers.
I am completely confused now; why would that unused array affect the middle of the answer array?
Thanks and sorry for the long code! I will be grateful if someone could edit the code into a better example, I simply son't know what is with the code.
You do a silly thing in here:
m[i * j][l + 1 + (i * j) - i - j] = true;
Say, i=160, j=150, l=1... You will try to access m[24000][23692]... And you corrupt the stack, so behavior is undefined.
Next time try to use some profiler and/or debugger.
Add:
#include <cassert>
at the begining and
assert( (i * j) * 12001 + (l + 1 + (i * j) - i - j) <= 12001*24001 );
before the following line:
m[i * j][l + 1 + (i * j) - i - j] = true;
The assertion will fail, which means you write outside the bounds of the array m.
As requested, adding this to an answer.
You are definitely writing beyond the bounds of the array m somewhere, when the unused array p exists, m overwrites in to its contents which doesn't affect the answer array but once p is removed the overwriting happens in to answer array showing up the problems.
Overwriting beyond the bounds of the array is an Undefined Behavior and it causes your program to be ill-formed. With Undefined Behavior all safe bets are off and any behavior is possible. While your program may work sometimes or crash sometimes or give incorrect results.Practically, Anything is possible and the behavior may or even may not be explainable.
In one of your nested loops you use l as the index for the second dimension. This variable can run from 0 to i and i, in turn, can run from 0 to 24000. Since your second dimension of the array can only be index from 0 to 12000 this causes a classic out of range error. This also nicely explains why adding an extra array avoid the problem: the out of range accesses go to the "unused" array rather than overwriting the result.

C++: delete strange behaviour

I have started doing some stuff with dynamic allocation in C++ but I had some problems. Here's the code:
nrMare(char cifS[], char* startPos = new char())
{
n = 0;
int i;
cif = startPos;
printf("%p %i\n", cif, (cif - (char*)NULL) % 8);
for(i = strlen(cifS) - 1; i >= 0; i--)
{
cif--;
n++;
cif = new(cif) char(cifS[i] - '0');
}
}
~nrMare()
{
int i;
for(i = 0; i < n; i++)
{
delete(cif);
cif++;
}
n = 0;
cif = 0;
}
nrMare is a class (it comes from bigNumber in Romanian :D) which is supposed to be able to contain the digits of a big number.
The problem is that the destructor (~nrMare) gives a weird error, when I make a variable nrMare something() on my computer, but it works for 116 digits long ones.
Do you have any suggestion or explainations?
EDIT: cif is a (char*) type
EDIT #2: n is the length of the number. I use the char pointer this way because I want to be able to add (like n++; cif--; cif = new(cif) char(number_to_add); -> this would add number_to_add in the left side of cif) and draw elements from both sides.
EDIT #3: this is gonna be a long one... Sorry for being such a bad explainer and thanks for your patience.here are some operators:
void operator-=(nrMare nr2)
{
int i;
for(i = 1; i <= n && i <= nr2.n; i++)
cif[n - i] -= nr2[nr2.n - i];
for(i = n - 1; i >= 0; i--)
{
if(cif[i] < 0)
{
cif[i] += 10;
cif[i - 1]--;
}
}
while(cif[0] == 0)
{
cif++;
n--;
//delete(cif - 1);
}
}
int operator/=(int nr)
{
int i;
for(i = 0; i < n - 1; i++)
{
cif[i + 1] += (cif[i] % nr) * 10;
cif[i] = cif[i] / nr;
}
i = cif[n - 1] % nr;
cif[n - 1] /= nr;
while(cif[0] == 0)
{
cif++;
n--;
//delete(cif - 1);
}
return i; // the return value is this big number % nr
}
void operator*=(int cifTimes)
{
int i;
for(i = 0; i < n; i++)
{
cif[i] *= cifTimes;
}
for(i = n - 1; i >= 0; i--)
{
if(cif[i] > 9)
{
if(i != 0)
{
cif[i - 1]++;
cif[i] %= 10;
}
else
{
n++;
cif[0] %= 10;
cif--;
cif = new(cif) char(cif[0] = 1);
}
}
}
}
EDIT #4: n = length of the number = number of digits = number of bytes. Weird error means it just crashes. I don't know how to find more about it. MinGW compiler asks Visual Studio (Visual C++) to debug it because it has some problems. This is for a problem, and somewhere (in the evaluator) it says "Killed by signal 6(SIGABRT)", if this helps.
EDIT #...: #Branko Dimitrijevic: I don't wanna be lazy... I want my own... I had this problem in more attempts to make something running. If I take out the destructor, it works just fine, just I guess then it would be a memory leak that way... I really want to find out why would this occur... and only for specific sizes and, i.e. it doesn't crash on the first "delete", but on the 11'th in my case, that's why it's weird .
The delete can only work correctly on an address that is at the beginning of a dynamically-allocated block.
The cif will fail one or both of these conditions, leading to undefined behavior when the destructor calls delete, for following reasons:
You assign startPos to cif and then modify it in a very strange way before calling the placement new. So even if startPos is a properly allocated block of dynamic memory, the cif no longer points to the starting address of it.
If the caller passes an address of a stack-based variable to startPos, then you no longer deal with dynamic memory at all.
Not to mention that you call new and delete in a loop - what's up with that? There is also a fair chance for bombarding the memory unless you craft your input parameters in a very specific way. This whole block of code looks suspicious, what exactly are you trying to do?