Comparison between signed and unsigned integer expressions - c++

I just started using OpenGL. This is my first code:
// OpenGL hello program
#include<iostream>
#include <GL/glut.h>
#include <cstring>
void display() {
glClear(GL_COLOR_BUFFER_BIT);
char message[] = "Hello, world!";
glRasterPos2d(0, 0);
for (int i = 0; i < sizeof(message) / sizeof(message[0]); i++)
{
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, message[i]);
}
}
int main(int argc, char *argv[]) {
glutInit(&argc, argv);
glutInitWindowSize(500, 500);
glutCreateWindow("OpenGL hello program");
glutDisplayFunc(display);
glutMainLoop();
}
The error I am getting is: Warning: comparison between signed and unsigned integer expressions (line 9).
I also tried writing a new code then to see whats causing the problem:
#include<iostream>
#include <cstring>
void display1() {
char message[] = "Hello, world!";
for (int i = 0; i < sizeof(message) / sizeof(message[0]); i++)
std::cout<<message[i];
}
int main() {
display1();
}
This code works perfectly fine. Why is the first code not working fine?
EDIT:
Following up on Cyber's annswer, I changed the loop to:
for (unsigned int i = 0; i < sizeof(message) / sizeof(message[0]); i++)
But the OpenGL code does not do the expected i.e. show "Hello, world!" message in the window. It just creates a window with "OpenGL hello program" written at the top and nothing else.

This line is the problem
for (int i = 0; i < sizeof(message) / sizeof(message[0]); i++)
The operator sizeof has the return type of std::size_t which is therefore what you should use for the type of your variable i. std::size_t is an unsigned type, so the compiler is warning you that you are comparing a signed type (int) to an unsigned type, because the comparison is potentially unsafe if the value of one variable is not in the representable range of in the other type.
for (std::size_t i = 0; i < sizeof(message) / sizeof(message[0]); ++i)
Or simply use a range-based for loop.
for (auto i : message)
{
std::cout << i; // i is a char from the message array
}

for (int i =0,i<sizeof ....)
That line is the problem. The sizeof function returns an unsigned integer thus causing error when compared to the signed int.
Try creating an int variable for the sizeof like this:
int size=sizeof()...
Then replace in your line as follows:
for (int i=0,i<size...)

Related

Function and Pointers to find the amplitude (largest value) of a signal in an array

my lecturer created this function in a live code clinic and I am trying to copy it out then re-write it multiple times until I have learnt and understood the code.
Currently I'm unsure where I need to define the "findgreatest" function for the program to run. I was under the impression that you had to define functions within the main(). However, there are likely more errors I'm not seeing. Anyways, some help to get this code running and explained in more detail would be greatly appreciated.
Thanks
Alex
#include <iostream>
#include <ctime>
using namespace std;
int main(int argc, const char * argv[]) {
const unsigned int size = 15; // creates a const int for array
int a_sig [size]; // assigns int to array size
for(int i=0; i<size; i++) {
a_sig[i] = rand() % 100;
cout << *(a_sig+i) << endl;
}
int findgreatest (int size, int a_sig) { //"F deceleration not allowed"
int max = -1;
for (int i = 0; i < size; i++) {
if (*(a_sig+i) > max){
max = *(a_sig+i);
}
}
return max;
};
int maximum;
maximum = findgreatest(size, a_sig); //"undeclared identifier"
return 0;
};
Currently I'm unsure where I need to define the "findgreatest" function for the program to run. I was under the impression that you had to define functions within the main().
Actually, you cannot define named functions in main. You can see this in the error declaration not allowed.
Functions must be declared before use. During compilation, the compiler will note where functions are defined. When the compiler sees one of these functions called, it knows what instructions to put since it is aware that these functions exist. But if a function isn't declared (and defined), then the compiler cannot interpret function calls.
You should either define your function before main, or declare your function before main and define it after main.
Option: Defining function before main
If you want to define the function before main, your code might look like
#include <iostream>
#include <ctime>
#include <cstdlib> // rand is defined here
using namespace std;
// Defines findgreatest
// findgreatest is now available for use later in program
int findgreatest (int size, int a_sig[]) // I added a `[]` in this signature
{
int max = -1;
for (int i = 0; i < size; i++) {
if (*(a_sig+i) > max){
max = *(a_sig+i);
}
}
return max;
}
int main(int argc, const char * argv[]) {
const unsigned int size = 15; // creates a const int for array
int a_sig [size]; // assigns int to array size
for(int i=0; i<size; i++) {
a_sig[i] = rand() % 100;
cout << *(a_sig+i) << endl;
}
int maximum;
maximum = findgreatest(size, a_sig);
// You probably want to do something with the maximum?
cout << "\nMaximum is " << maximum << endl;
return 0;
} // (I removed an unnecessary semicolon here)
Option: Declaring function before main, define after
Alternately, you can declare the function (i.e. give a description of its name and signature) and define it later. You can do this with
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
// declares findgreatest
// The compiler knows that this function is defined somewhere and can make
// references to it. If the definition isn't also provided during compilation,
// an error is raised.
int findgreatest (int size, int a_sig[]);
int main(int argc, const char * argv[]) {
const unsigned int size = 15; // creates a const int for array
int a_sig [size]; // assigns int to array size
for(int i=0; i<size; i++) {
a_sig[i] = rand() % 100;
cout << *(a_sig+i) << endl;
}
int maximum;
maximum = findgreatest(size, a_sig);
// You probably want to do something with the maximum?
cout << "\nMaximum is " << maximum << endl;
return 0;
}
// Definition
int findgreatest (int size, int a_sig[])
{
int max = -1;
for (int i = 0; i < size; i++) {
if (*(a_sig+i) > max){
max = *(a_sig+i);
}
}
return max;
}
Additional notes
To use rand(), you need to #include <cstdlib>.
You compute maximum but don't do anything with it. I added a statement outputting this to the terminal at the end of main.
I removed a semicolon after main(){}.
Your function signature findgreatest(int size, int a_sig) isn't quite right. The second argument is an array, not an int. There are a few different ways to denote this, but I changed it to findgreatest(int size, int a_sig[]) to indicate to the compiler that it should be expecting an array.
When you learn more about arrays, you'll know a bit more about that. And you'll probably revisit the expressions *(a_sig + i), which are a bit odd.

I am trying to run this C++ code but its showing me error, can you tell me what is wrong?

int initfunc(int *array, int len)
{
int i;
for(i=1; i <= len; i++)
{
array[i] = i;
}
return 0;
}
int main(int argc, char* argv[])
{
int *myarray = 0;
initfunc(myarray, 10);
}
I have run this code in C++ but showing me error. can you please tell me what is wrong with code.
Okay first of all you have to change the line
int *myarray = 0;
You have two options you can generate an array on the stack and on the heap. The stack example looks like this:
int myarray[10];
Where 10 is the size of you array.
Second your for loop is running out of bounds. You have to start with the index 0 and iterate up to array size -1. In our example 10-1=9
So you have to change the line
for(i=1; i <= len; i++)
to
for(i=0; i < len; i++)
the whole project should look like this:
int initfunc(int *array, int len)
{
int i;
for(i=0; i < len; i++)
{
array[i] = i;
}
return 0;
}
int main(int argc, char* argv[])
{
int myarray[10];
initfunc(myarray, 10);
}
I'm ignoring certain "best practices" in this example to be as close to your code as possible. One good intention would be to declare the length of that array just once and also bring that int i into the loop scope. Im leaving this here for you to try and exercise.

command line argument in c++ segmentation fault

i am trying to use command line argument in Linux(Ubuntu) in c++ . but it generates run time error : segmentation fault.this program runs with no error in windows .here is my code
#include<iostream>
using namespace std;
int main(int argc , char **argv){
char **ss;
for(int i=0;i<argc;i++){
ss[i] = argv[i];
}
for(int i=0;i<argc ;i++)
cout<<ss[i];
return 0;
}
what is wrong with this code. please help me . thanks in advance.
Your program has undefined behaviour because you did not initialize pointer ss and allocate memory where you are going to copy elements pointed by argv
char **ss; // What value does it have?
for(int i=0;i<argc;i++){
ss[i] = argv[i];
You could do the following way
char **ss = new char *[argc];
for(int i=0;i<argc;i++){
ss[i] = argv[i];
The better way is to use std::vector<std::string>. In this case you could also copy not only pointers to arguments but and also the arguments. For example
#include<iostream>
#include <vector>
#include <string>
int main(int argc , char **argv)
{
std::vector<std::string> v( argv, argv + argc );
for ( const std::string &s : v ) std::cout << s << std::endl;
return 0;
}
If your compiler does not support the range based for statement then you can substitute it for
for ( std::vector<std::string>::size_type i = 0; i < v.size(); i++ )
{
std::cout << v[i] << std::endl;
}
As already answered, you haven't allocated any memory for ss.
Since you're using c++ and not c, you should have the c++ standard library at your disposal:
std::vector<std::string> ss;
ss.reserve(argc); // not necessary
for(int i=0;i<argc;i++)
ss.push_back(argv[i]);
Use the following declaration for ss
#include<iostream>
using namespace std;
int main(int argc , char **argv){
char *ss[argc]; // <--allocate argc count of pointers
for(int i=0;i<argc;i++){
ss[i] = argv[i];
}
for(int i=0;i<argc ;i++)
cout<<ss[i];
return 0;
}

sigsegv error in aggregate method

Here is my code:
#include <cstdlib>
#include <stdio.h>
#define NUM_READINGS 3
int* readingsTotal;
int* readingsAverage;
int readingsIndex;
using namespace std;
void avgOf(int* toFindAvgOf, int size) {
int i;
for (i = 0; i < size; i++) {
// Add reading to total for each component.
readingsTotal[i] += toFindAvgOf[i];
// Once method has been iterated through n (NUM_READINGS) times:
if (readingsIndex == NUM_READINGS - 1) {
// Set the arithmetic mean.
readingsAverage[i] = readingsTotal[i] / NUM_READINGS;
// Reset the total.
readingsTotal[i] = 0;
}
}
readingsIndex++;
}
int iterate(int findAvgOf) {
int toFindAvgOf[] = {findAvgOf, 20, 30};
avgOf(toFindAvgOf, sizeof (toFindAvgOf));
return readingsAverage[0];
}
int main(int argc, char** argv) {
readingsTotal = (int []){0, 0, 0};
readingsAverage = (int []){0, 0, 0};
int i;
for (i = 0; i < 3; i++) {
int smthd = iterate(12 + i * 2);
printf("%d\n", smthd);
}
return 0;
}
When I run this in netbeans c/c++, it builds with now errors but when it executes it fails and prints:
RUN FAILED (exit value 1, total time: 86ms)
When I go into debug mode it also fails immediately and gives the SIGSEGV error. From reading online I'm guessing there is some issue with the way I am dereferencing a pointer. But I have no clue where exactly it is failing at. I am pretty new to c++ so any help would be great!
In C, the sizeof function returns the size of the object in bytes.
So when you say:
sizeof (toFindAvgOf)
That will return 12 (assuming an int on your system is 4-bytes) thus causing an index out of bounds condition in the avgOf function.
To get the length of the array:
sizeof(toFindAvgOf) / sizeof(int)

c++ array to vector issue

Im trying to copy an array to a vector, however, when the data is copied to the vector its different from that of the original array.
int arraySize = 640000;
std::vector<unsigned char> vector_buffer;
unsigned char buffer[arraySize];
populateArray(&buffer);
for(int i = 0; i < arraySize; i++)
cout << buffer[i]; // this prints out data
std::copy ( buffer, buffer + arraySize, std::back_inserter(vector_buffer));
for(int i = 0; i < arraySize; i++)
cout << vector_buffer[i]; // this prints out different data
The data seems to get compressed somehow. Any approach at copying the array to a vector does the same thing.
Im using it to create a video from images. If i use the array data all is well, but if i use the vector data it doesn't work.
Any help would be highly appreciated.
Cheers
The
int arraySize = 640000;
needs to be const in standard C++. g++ allows variable length arrays as a C99-inspired language extension. It's best to turn that extension off. :-)
std::vector<unsigned char> vector_buffer;
unsigned char buffer[arraySize];
OK when arraySize is const, but will not compile with e.g. Visual C++ with your original code.
populateArray(&buffer);
This should most probably be populateArray(buffer), unless you have a really weird declaration of populateArray.
for(int i = 0; i < arraySize; i++)
cout << buffer[i]; // this prints out data
The above prints the data with no spacing between the elements. Better add some spacing. Or newlines.
std::copy ( buffer, buffer + arraySize, std::back_inserter(vector_buffer));
Better just use the assign method of std:.vector, like vector_buffer.assign( buffer, buffer + arraySize ).
for(int i = 0; i < arraySize; i++)
cout << vector_buffer[i]; // this prints out different data
Again, this displays the elements with no spacing between.
Is the apparent problem there still when you have fixed these things?
If so, then please post also your populateArray function.
I can see nothing wrong with your code. The following code
#include <iostream>
#include <vector>
int main()
{
const std::size_t arraySize = 640000;
unsigned char buffer[arraySize];
for(std::size_t idx = 0; idx < arraySize; ++idx)
buffer[idx] = idx;
std::vector<unsigned char> vector_buffer(buffer, buffer + arraySize);
//std::vector<unsigned char> vector_buffer;
//std::copy (buffer, buffer + arraySize, std::back_inserter(vector_buffer));
for(std::size_t idx = 0; idx < arraySize; ++idx)
if( buffer[idx] != vector_buffer[idx] )
{
std::cout << "error #" << idx << '\n';
return 1;
}
std::cout << "Ok.\n";
return 0;
}
prints Ok. for me. (Even if I use the less-than-optimal way of copying into the vector.)
From the fact that the code you showed wouldn't compile I conclude that you're not showing the real code. Please do so. Somewhere in the differences between your real code and my code must be the problem.
I've written a complete compilable program for you. The code appears fine. I run it and get expected output. Perhaps you need to re-check the code you posted against the real code.
#include <cstdlib>
#include <vector>
#include <iostream>
#include <iterator>
using namespace std;
void populateArray(unsigned char* buf, size_t buf_size)
{
unsigned char* buf_end = &buf[buf_size];
for( unsigned char c = 'A'; buf != buf_end; c = (c=='Z'?'A':c+1), ++buf )
*buf = c;
}
int main()
{
static const int arraySize = 64;
std::vector<unsigned char> vector_buffer;
unsigned char buffer[arraySize];
populateArray(buffer, sizeof(buffer));
for(int i = 0; i < arraySize; i++)
cout << buffer[i]; // this prints out data
cout << endl;
std::copy ( buffer, buffer + arraySize, std::back_inserter(vector_buffer));
for(int i = 0; i < arraySize; i++)
cout << vector_buffer[i]; // this prints out different data
return 0;
}