get error while trying to access a list [closed] - c++

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
I've got a list with a struct:
struct structPlacedBets
{
int betOption = 0;
int betValue = 0;
int betChips = 0;
int player = 1;
}
the list:
list <structPlacedBets> placedBets;
when writing to the list, there is no problem. I fill a temporary variable with the data, and then I handover the temporary variable to the list.
placedBets.push_back (tempPlacedBets);
Everything fine.
I also can access the list in the main function, everything good.
But, I wanted to handover the memory adress from the list to a function, and then output everything from the list. In the moment where I try to access the data, my program crashes.
Here is the code:
struct structPlacedBets
{
int betOption = 0;
int betValue = 0;
int betChips = 0;
int player = 1;
}
list <structPlacedBets> placedBets;
structPlacedBets tempPlacedBets; //temporary variable for filling the list
.
.
.
placedBets.push_back (tempPlacedBets);
.
.
.
void outputList(list <structPlacedBets> &tempList)
{
list <structPlacedBets>::iterator Iterator;
for (Iterator == tempList.begin(); Iterator != tempList.end(); Iterator++)
{
cout << Iterator->betOption; //here the program crashes
}
}
int main()
outputList(placedBets);
return 0;
When accessing the list directly in the main, without another function, everything is fine.
Works well:
int main()
list <structPlacedBets>::iterator Iterator;
for (Iterator = placedBets.begin(); Iterator != placedBets.end(); Iterator++)
{
cout << (*Iterator).betOption << endl;
cout << (*Iterator).betValue << endl;
cout << (*Iterator).betChips << endl;
cout << (*Iterator).player << endl;
}
Hope, anybody knows the problem and the answer.
Thank you.

In the first example, you have a typo:
for (Iterator == tempList.begin(); Iterator != tempList.end(); Iterator++)
// ^^
Iterator was never initialised to anything! Comparing it, then dereferencing it (and, if you got that far, incrementing and comparing it again) all has undefined behaviour.
In the second example you correctly wrote =.
Pay closer attention to your code, and turn on your compiler's warnings.

Related

I have made a program to implement stack but it is not working properly [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed last month.
Improve this question
The code is not throwing any error but it is not taking the values that we pass in the enqueue function.
Here is the code:
#include <bits/stdc++.h>
#include <climits>
using namespace std;
struct Queue{
int *arr;
int front , rear;
int cap;
Queue(int c){
cap = c;
front = -1;
rear = -1;
arr = new int[cap];
}
void enqueue(int x){
if(rear == cap-1){
cout<<"The array is full";
}
rear++;
arr[rear] == x;
cout<<arr[rear]<<endl;
if(front == -1){
front = 0;
}
}
int dequeue(){
int data;
if(front == -1){`your text`
cout<<"Array is empty";
return INT_MIN;
}
data = arr[front];
arr[front] = 0;
if(front == rear){
front = rear = -1;
}
else{
front++;
}
return data;
}
};
int main() {
Queue q(3);
q.enqueue(24);
q.enqueue(30);
q.enqueue(42);
cout<<q.dequeue();
return 0;
}
the enqueue function is taking some garbage value instead of the integer value that we are passing in the argument.
Hi and welcome to Stackoverflow.
The problem is that you ignored your compiler warnings. Under https://godbolt.org/z/Pn1Mf115T i have thrown your code in an online compiler and it tells me/you:
<source>:20:19: warning: equality comparison result unused [-Wunused-comparison]
arr[rear] == x;
~~~~~~~~~~^~~~
<source>:20:19: note: use '=' to turn this equality comparison into an assignment
arr[rear] == x;
^~
=
1 warning generated.
Compiler returned: 0
So the compiler tells you that you comparing instead of assigning the values. Thats the reason why your queue takes garbage values, it just never gets data assigned and the output is the uninitialized memory from your C-style array.
Rule of thumb: Do not ignore compiler warnings.

Why am I getting this writing access violation error? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 4 months ago.
Improve this question
I'm not sure why this is happening. Updated my original post to add in the suggestions made thank you everyone for your help!
The issue function was made by my professor. The function I am making is the board() function.
MY FUNCTION
TourBus& TourBus::board()
{
char passName[40];
int i = 0;
cout << "Boarding " << busSizeNumber << " Passengers: " << endl;
for (i = 0; i < busSizeNumber; i++)
{
cout << i + 1 << "/4- Passenger Name: ";
cin.getline(passName, 40,'\n');
ticket->issue(passName);
}
return *this;
}
MY PROFESSOR'S FUNCTION
TourTicket& TourTicket::issue(const char* passengerName) {
if (passengerName && passengerName[0]) {
copyName(passengerName);
m_ticketNumber = next_ticketNumber++;
}
return *this;
}
void TourTicket::copyName(const char* str) {
int i = 0;
for (i = 0; i < 40 && str[i]; m_name[i] = str[i], i++);
m_name[i] = 0;
}
This is a picture of the instructions for this function:
this is the picture of the error
the variables i am watching are all holding the string correctly however its just not copying it and throwing that error
In this line, the method declares a pointer but doesn't initialize it to point to anything:
char* passName;
... and then in this line you call getline() and pass in the uninitialized pointer as an argument:
cin.getline(passName, 20,'\n');
getline() will try to write some text into the buffer that passName is pointing to... but passName is uninitialized, so it is not pointing to any well-defined region of memory. Hence, the attempt to dereference it invokes undefined behavior, and you get a write-access error.
I think you'd get a result more in line with what you wanted if you changed the passName declaration to something like this:
char passName[20]; // allocates 20 bytes of stack space to hold chars in

bool vs void vs print or std::cout [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
What is the difference between having a void or a bool and why is the answer not displaying right? The more I look up and try to understand the deeper I dig myself into a whole. (eg: std::boolalpha)?!?
#include <iostream>
#include <stdio.h>
#include <vector>
bool findPair(int* arr, int arrLength, int k)
{
for(int i=0; i<arrLength; i++)
{
for(int j = i+1;j<arrLength; j++)
{
if(arr[i] + arr[j] == k)
{
printf("Pair Found (%d, %d)", arr[i], arr[j], "\n");
//return;
}
}
}
printf("Pair NOT Found!");
//return false;
}
int main()
{
int array[5] = {4,5,1,7,2};
int sum = 221;
int arrLength = sizeof(array)/sizeof(array[0]);
findPair(array, arrLength, sum);
std::cout << std::endl << findPair() << std::endl;
// return 0;
}
Gives the following output when a pair is found (int sum = 3;):
Pair Found (1, 2)Pair NOT Found!
1
And this output when the pair is not found (int sum = 221;):
Pair NOT Found!
1
Right now, you've told the compiler that findPair returns a bool, but the method doesn't actually return true or false. You've lied to the compiler, and the compiler is allowed to do whatever it wants in this case. A function with a return type should always have a return statement that tells the compiler what value to return to the caller (or throw an exception).
A method with a void return type does not have to have a return; statement, and it's return; statements do not have to return a value, but you can still use return; statements to tell the computer to stop executing the method and return to the caller.
In your case, since you've eliminated the return statement after "Pair Found (%d, %d)", the method keeps executing, until it reaches the end of the loop, which is why you see both printf statements execute. Make sure to put a return type there.
Separately, std::cout << findPair will try print the address of the function, but since there's no overload for that, it will convert the pointer to a boolean, thus printing 1. What you probably wanted was to store the returned value into a bool variable, and send that to cout?
If you want to output true or false instead of 1 or 0 for bool types, then stream out std::boolalpha first, as in std::cout << std::boolalpha << myBoolean;

How can I fix an assertion failure that states 'vector subscript out of range' [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
Other questions that I viewed before posting this question:
Debug Assertion Failed: Vector subscript out of range
Debug Assertion Failed Vector Subscript Out of Range C++
I am working on a Boids project, details of which can be found here:
https://www.red3d.com/cwr/boids/
From what I can gather my issue is something to do with an index getting accessed by the function but no data is present in the index. I had this issue yesterday in a different area of my code and fixed it by making one of my getters return a reference rather than a copy of a class object. That approach seems to not be the issue today.
Below is my code:
This code is a snippet from my function that handles simulation events. This is the code that I have narrowed down the issue to.
//Remove flocking organisms with < 0 enery storage.
for (int i = 0; i < m_flock.getSize(); i++)
{
if (m_flock.getOrganism(i).getEnergyStore() <= 0)
{
m_flock.removeOrganism(i);
//m_notFlocking.flock.erase(m_notFlocking.flock.begin() + i);
cout << "Organism died and has been removed..." << endl;
}
}
The code below is from my Flock.cpp class definition file which details information on storing boids in a vector to then apply flocking behaviors to. This class function is giving the following error:
Unhandled exception at 0x7B87FC66 (ucrtbased.dll) in EvoSim.exe: An invalid parameter was passed to a function that considers invalid parameters fatal.
Code:
Organism &Flock::getOrganism(int i)
{
return flock[i];
}
My suspicion is that the for loop size is not reflecting the recently erased object.
How can I fix the vector subscript error?
Edit:
This is the break point that shows up in the debugger:
_NODISCARD _Ty& operator[](const size_type _Pos) noexcept /* strengthened */ {
auto& _My_data = _Mypair._Myval2;
#if _CONTAINER_DEBUG_LEVEL > 0
_STL_VERIFY(
_Pos < static_cast<size_type>(_My_data._Mylast - _My_data._Myfirst), "vector subscript out of range");
#endif // _CONTAINER_DEBUG_LEVEL > 0
return _My_data._Myfirst[_Pos];
}
Edit 2:
I did some messing around and discovered the issue only occurs when I run VS 2019 in debug mode, otherwise in Release mode it works fine and as expected.
I see nothing in this code that can cause an out of bounds access. However, you should not increment i on any loop iteration that removes an organism, otherwise you will skip the next organism in the list.
Imagine on the 1st loop iteration, the organism at index 0 needs to be removed. Subsequent organisms move down the list. On the next loop iteration, i gets incremented to 1, and the organism that had moved into index 0 is skipped.
Try this instead:
//Remove flocking organisms with < 0 enery storage.
for (int i = 0; i < m_flock.getSize(); )
{
if (m_flock.getOrganism(i).getEnergyStore() <= 0)
{
m_flock.removeOrganism(i);
cout << "Organism died and has been removed..." << endl;
}
else
++i;
}
Alternatively, you can replace the entire loop using the erase-remove idiom via std::remove_if() and std::vector::erase(), eg:
void Flock::removeDeadOrganisms()
{
//Remove flocking organisms with < 0 enery storage.
flock.erase(
std::remove_if(flock.begin(), flock.end(),
[](const auto &o){ return o.getEnergyStore() <= 0; }
),
flock.end()
);
}
...
m_flock.removeDeadOrganisms();
Or, in C++20, via std::erase_if(), eg:
void Flock::removeDeadOrganisms()
{
//Remove flocking organisms with < 0 enery storage.
std::erase_if(flock,
[](const auto &o){ return o.getEnergyStore() <= 0; }
);
}
To loop though a vector that you are also modifying you don't want to i++ on every loop, since if the element was removed you don't need to increment the index. There are two solutions to this, either you can conditionally increment the index at the end of the loop or you can loop though the list backwards.
int i = 0;
while (i < m_flock.getSize())
{
if (m_flock.getOrganism(i).getEnergyStore() <= 0)
{
m_flock.removeOrganism(i);
cout << "Organism died and has been removed..." << endl;
}
else
{
i++;
}
}
for (int i = m_flock.getSize(); i ; i--)
{
if (m_flock.getOrganism(i).getEnergyStore() <= 0)
{
m_flock.removeOrganism(i);
cout << "Organism died and has been removed..." << endl;
}
}
You can't use a normal iterator loop for this because vector::erase "Invalidates iterators and references at or after the point of the erase, including the end() iterator". However, you can use std::remove_if.
m_flock.erase(std::remove_if(m_flock.begin(),
m_flock.end(),
[](Organism org){
return org.getEnergyStore()<=0;
}));

C++: invalid use of 'void' [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
This code should print i = 35 as result but somehow it doesn't even compile. Why ?
#include <iostream>
using namespace std;
void increment(int &p){
p = p +10;
}
int main()
{
int i = 10;
increment(i) += 15;
cout<<"i = " <<i<<endl;
return 0;
}
No it shouldn't! increment has void as return type, that means that an expression call to this function has no value. If you want that call to be able to be used on the left part of an assignment, it must return a left-value.
Basically, when you write a=b a denotes a container but b a value.
You can try:
int &increment(int &p){
p = p +10;
return p; // return the reference passed as argument...
}
int main()
{
int i = 10;
increment(i) += 15;
cout<<"i = " <<i<<endl;
return 0;
}