Function keeps overwriting previous structure data [closed] - c++

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 6 years ago.
Improve this question
when I enter data using my add function, I am able to print them no problem. Adding a vaule for start(x,y), end(x,y) works and I am able to print the values. But when I specify that I want two numGraphicElements when the function leaves after entering the first set of start and end values. It overwrites my previous values when going through the loop a second time.
When I print the values it for some reason overwrites my first values with random numbers and then only shows the second set of start(x,y) end(x,y) values.
example of first set: start(1,2) end (3,4)....this print properly
example of second set added: start(9,8) end (6,7)...this prints as well
example pf print out with 2 sets together, x(23424), y(653243), end = x(2334) y(33434).....x(9) y(8) end x(3) y(4).
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <crtdbg.h>
#define _CRTDBG_MAP_ALLOC
enum
{
RUNNING = 1
};
struct Point
{
int x, y;
};
struct Line
{
Point start;
Point end;
};
struct GraphicElement
{
enum
{
SIZE = 256
};
unsigned int numLines; //number of lines
Line* pLines; //plines points to start and end
char name[SIZE];
};
typedef struct
{
unsigned int numGraphicElements;
GraphicElement* pElements; //the head points to pLines
} VectorGraphic;
void InitVectorGraphic(VectorGraphic*);
void AddGraphicElement(VectorGraphic*);
void ReportVectorGraphic(VectorGraphic*);
VectorGraphic Image;
int main()
{
char response;
InitVectorGraphic(&Image);
//for debugging purposes
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
//main menu for the program
while (RUNNING)
{
printf("\nPlease select an option:\n");
printf("1. Add a Graphic Element\n");
printf("2. List the Graphic Elements\n");
printf("q. Quit\n");
printf("CHOICE: ");
fflush(stdin);
scanf("%c", &response);
switch (response)
{
case '1':
AddGraphicElement(&Image);
break;
case '2':
ReportVectorGraphic(&Image);
break;
case 'q':
CleanUpVectorGraphic(&Image);
return 0;
default:
printf("Please enter a valid option\n");
}
printf("\n");
}
}
/*initialize the vectors, allocate memory*/
void InitVectorGraphic(VectorGraphic * pImage)
{ //addres of pImage is passed in
struct GraphicElement *pElements;
pImage->pElements = (GraphicElement*) malloc(sizeof(GraphicElement)); //pImage is now the addess of image
pElements = (GraphicElement*) malloc(sizeof(GraphicElement));
pImage->numGraphicElements = 8;
pImage->pElements = NULL;
}

Here
line = (struct Line *) malloc(sizeof(Line));
the code allocates exactly one line-object.
Here its seems to address more then just line[0]:
line[pImage->numGraphicElements]....
Doing so the code invokes undefined behaviour, anything can happen from this moment on. This includes overwriting other memory belonging to the same process.

Related

ERROR: run-time check failure #2 - stack around the variable was corrupted

I was trying to read a struct from a .text file and then save it in a new text file to see if it worked, but when it's getting saved the infamous error appears "run-time check failure #2 - stack around the variable 'pers' was corrupted".
I don't know which size I should give to the struct persona pers in order for it to work.
This is the .txt file:
Mirio Togata
18937332
15/7/1951
Shigaraki Tomura
17304739
24/11/1930
And this is the code:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#define LNOM 32
#define TAM 2 /*The size I established for the struct persona is 2 because there are 2 people*/
struct fecha { int d, m, a; };
struct persona
{
char nombre[LNOM];
int dni;
struct fecha nacim;
};
int readText(struct persona l[], int cant)
{
printf("Leyendo...\n");
char nom[LNOM];
FILE *pf = fopen("persona.txt", "r");
if (pf)
{
fgets(nom, LNOM, pf);
while (!feof(pf))
{
strcpy(l[cant].nombre, nom);
fscanf(pf, "%d", &l[cant].dni);
fgetc(pf);
fscanf(pf, "%d/%d/%d", &l[cant].nacim.d, &l[cant].nacim.m, &l[cant].nacim.a);
fgetc(pf);
cant++;
fgets(nom, LNOM, pf);
}
fclose(pf);
}
return cant;
}
void saveText(struct persona l[], int cant)
{
printf("Grabando...\n");
int i;
FILE *pf = fopen("personados.txt", "w");
if (pf)
{
for (i = 0; i < cant; i++)
{
fprintf(pf, "%s\n", l[i].nombre);
fprintf(pf, "%d\n", l[i].dni);
fprintf(pf, "%d/%d/%d\n", l[i].nacim.d, l[i].nacim.m, l[i].nacim.a);
}
fclose(pf);
}
}
int main(void)
{
int cant = 0;
struct persona pers[TAM];
cant = readText(&pers[TAM],cant);
saveText(&pers[TAM],cant);
return 0;
}
Thanks in advance.
First a refresher of array indexing.
pers[0]
provides the first persona in pers.
pers[1]
would provide the second, and
pers[2]
would be the third. This sequence can go on for quite a while, but because
#define TAM 2
will substitute all TAMs for 2
struct persona pers[TAM];
becomes
struct persona pers[2];
so pers has only two valid entries. This also means
pers[TAM]
becomes
pers[2]
which we saw above gets the third element in pers, and we now know there is no third element in pers.
So
cant = readText(&pers[TAM],cant);
Gets the address of the non-existent third element of pers and passes it into into readText as l. Since l is pointing outside the valid range for pers, reading into the element pointed at by l will corrupt the stack and cause the error message.
The solution is to read into a valid element of pers, &pers[0] or &pers[1]. Since two entries will be read from the file by readText, starting with &pers[1] and reading into element 2 and the non existent element 3 is not recommended.

Find Max and Min in an array type struct [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 7 years ago.
Improve this question
I am trying to find max, min , mean and average of an array type struct. I have a function "bsort" that sorts all my data using bubble sort in struct teams, which I call it here to sort my data fisrt. here is the code I am using to find the max:
void bfind(struct annual_stats *stats, int y, int year, string field, string item){
bsort(stats, y, year, field, "increasing");
if (item == "max"){
int max;
for (int i = 0; i < NO_TEAMS; i++) {
if (stats->teams->games[i] > max){
max = stats->teams->games[i];
}
}
}
}
where stats is a struct that has two elements, an integer and another struct:
struct annual_stats{
int year;
struct team_stats teams[ NO_TEAMS ];
};
Then I have these declarations:
#define NO_TEAMS 32 // Number of NFL teams
#define TEAM_NAME_LEN 25 // Maximum team name string length
#define TOP_LEN 6 // Maximum time of possession string length
and my struct teams is as follow:
struct team_stats{
char team_name[ TEAM_NAME_LEN ]; // Name of NFL team
int games; // Number of games played in the season
float pts_per_game; // Points per game
int total_points; // Total points
int scrimmage_plays; // Scrimmage plays
float yds_per_game; // Yards per game
float yds_per_play; // Yards per play
float first_per_game; // First downs per game
int third_md; // Third down conversions
int third_att; // Third down attempts
int third_pct; // Third down percentage
int fourth_md; // Fourth down conversions
int fourth_att; // Fourth down attempts
int fourth_pct; // Fourth down percentage
int penalties; // Number of penalties
int pen_yds; // Penalty yards
char top_per_game[ TOP_LEN ]; // Time of possession per game
int fum; // Number of fumbles
int lost; // Fumbles lost
int to; // Turnover ratio
};
and then teams is an array type struct which holds 20 elements in type int, float, and char.
what I am trying to do here is that I want to find the max on games, which is an int member of teams. When I run this program I keep getting an error that invalid types int[int] for array subscript.
I know if I remove [], my program compiles, but I think that I have to specify the element [i]?
Can anyone please give me some hints?
My program is reading the data from a text files.
BTW, I am not a pro in C++, so please explain in the simplest possible way!
Thanks.
void bfind(struct annual_stats *stats, int y, int year, string field, string item){
bsort(stats, y, year, field, "increasing");
if (item == "max"){
int max;
for (int i = 0; i < NO_TEAMS; i++) {
if (stats->teams[i].games > max){
max = stats->teams[i].games;
}
}
}
I think it should stats->teams[i].games

Overwhelmed by assignment based on Conway's Game of Life [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 8 years ago.
Improve this question
I am given files gameOfLife.cpp, life.cpp, and life.h. I am only allowed to edit life.cpp in order to make the program work. I don't know where to with editing life.cpp because there is so much going on that I am unfamiliar with. I am given a file checkoutLife.cpp to check my work.
I've spent the last two days looking at other people's Game of Life files trying to see how to proceed but am at a loss. I don't want someone to do my work for me but I need some direction.
gameOfLife.cpp
#include <iostream>
#include "life.cpp"
#include "life.h"
const int GENERATIONS=100;
using namespace std;
//make a random array of initial living cells
void gen(bool a[ROWS][COLS]){
for(int i=0;i<ROWS;++i){
for(int j=0;j<COLS;++j){
if(rand()%100<10)a[i][j]=true;
else a[i][j]=false;
}
}
a[5][5]=true;
a[5][6]=true;
a[5][7]=true;
return;
}
// check to see if two arrays are equal
bool equal(const bool a[ROWS][COLS], const bool b[ROWS][COLS]){
int i,j;
for(i=0;i<ROWS;++i)for(j=0;j<COLS;++j)if(a[i][j]!=b[i][j])return false;
return true;
}
//copy the b array into the a array
void copy(bool a[ROWS][COLS], const bool b[ROWS][COLS]){
for(int i=0;i<ROWS;++i){
for(int j=0;j<COLS;++j){
a[i][j]=b[i][j];
}
}
return;
}
//print out the array
void print(const bool a[ROWS][COLS]){
for(int i=0;i<ROWS;++i){
for(int j=0;j<COLS;++j){
if(a[i][j])cout << 'X';
else cout << ' ';
}
cout << endl;
}
return;
}
int main(){
bool current[ROWS][COLS];
bool next[ROWS][COLS];
int i=0;
//initialze the cell array and print it out
gen(current);
print(current);
while(i<GENERATIONS){
//get a carriage return before the next generation
cin.get();
//give the current generation to life()
//it puts the next generation into next
life(current,next);
//copy the next generation into the current
copy(current,next);
//print it out
print(current);
i++;
}
return 0;
}
life.cpp
/*1. You need to write a file life.cpp that implements the function prototyped in life.h. You can and should write other functions
and tuck them into the same file; whatever you need to get your function working in an elegant manner.
2. Compile your file with checkoutLife.cpp and run the resulting executable to see if it passes all the tests.
3. Compile yourfile with gameOfLife.cpp and run the resulting executable to see if it makes pretty pictures.
4. If you are convinced steps 2 and 3 are working, submit your life.cpp via canvas.
*/
#include <iostream>
#include <cstdlib>
#include "life.h"
using namespace std;
void life(const bool current[ROWS][COLS], bool next[ROWS][COLS]){
}
life.h
#ifndef LIFE_H
#define LIFE_H
const int ROWS=25;
const int COLS=25;
// Simulate one generation of Conways Game of Life
//
// Given:
// a constant 2D bool array called "current" where each true element
// indicates a live cell and each false element indicates a dead cell.
//
// an empty 2D bool array called "next"
void life(const bool current[ROWS][COLS], bool next[ROWS][COLS]);
#endif
life() is called with two parameters: an array of your board's current state (which presumably you will not touch) and an array of the board's next state (which you will populate).
Here is an algorithm you could use:
For each row in ROW:
For each col in COL:
Add up all surrounding neighbours in current[][], store in "neighbours"
If current[row][col] is alive and neighbours < 2, next[row][col] = dead
Else if current[row][col] is alive and neighbours == 2 or 3, next[row][col] = alive
Else if current[row][col] is alive and neighbours > 4, next[row][col] = dead
Else if current[row][col] is dead and neighbours == 3, next[row][col] = alive
You can clean up the logic a bit, but I printed it out just like the rules on Wikipedia's Game of Life entry. The complicated part (IMO) is "Add up all surrounding neighbours" - there's a lot of bounds checking here. I suggest calling a different method that you write, for clarity's sake.

I want to blink the LED's in reverse order [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 8 years ago.
Improve this question
I want to reverse the code as it complete first time. For example pin 1-pin 2-pin 3-pin 4 (it's complete) now it should run as pin 4-pin 3-pin 2-pin 1.
I wrote this code but it's not working in reverse order. Please guide me in this way.
#include<htc.h>
__CONFIG(1,OSCSDIS & HSPLL);
__CONFIG(2,BORDIS & PWRTDIS &WDTDIS);
__CONFIG(3,CCP2RC1);
__CONFIG(4,LVPDIS & STVREN);
__CONFIG(5,UNPROTECT);
__CONFIG(6,WRTEN);
__CONFIG(7,TRU);
define _XTAL_FREQ 40000000
void delay_sec(unsigned char seconds) // This function provides delay in terms of seconds
{
unsigned char i,j;
for(i=0;i<seconds;i++)
for(j=0;j<100;j++)
__delay_ms(10);
}
void led_display(char a)
{
switch(a)
{
case 0: PORTB=0x01;PORTD=0x08; break;
case 1: PORTB=0x02;PORTD=0x04; break;
case 2: PORTB=0x04;PORTD=0x02; break;
case 3: PORTB=0x08;PORTD=0x01; break;
}
}
void main()
{
TRISB=0x00; TRISD=0x00; char a,b;
while(1) {
led_display(a);
a++;
delay_sec(1);
if(a==4) {
a--;
}
}
}
For doing that, you have to remember in which order you are running (reverse or not). So you will have a variable indicating if the order is reverse or not, and change it when you reach the extremities of your counter (0 and 3)
And you can optimize the code with using 1 and -1 for the variable which remembers order and adding it to a.
Your code will seem like this in your main :
int reverse = 1,
char a = 0;
while(1)
{
led_display(a);
delay_sec(1);
if(a==3)
{
reverse=-1;
}
if(a==0)
{
reverse=1;
}
a+=reverse;
}
Regards.

C++ recursive algorithm for permutation [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 8 years ago.
Improve this question
The permute() function runs into an infinite loop and I can't seem to find why?
i tried checking the function by removing the recursive call and it seems to be working fine. I also have the base case, so don't know where is the problem.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
string smallString(string s, int k){ // computes a string removing the character at index k
int i,j;
string res;
for(i=0,j=0;j<s.length();i++,j++){
if(i==k){j++;}
res.push_back(s[j]);
}
return res;
}
void permute(string s1, string s2, size_t len){
if(len==1)
{cout<<"length is equal to 1"<<(s1+s2)<<'\n'; return;} //base case
else{
for(int i =0;i<len;i++){
string temp= s2.substr(i,1);
s1.append(temp);
string fin = smallString(s2,i);
//cout<<temp<<'\t'<<s1<<'\t'<<fin<<'\t'<<fin.length()<<'\n';
permute(s1,fin,fin.length());
s1.erase((s1.length()-1));
//cout<<"printing s1 : "<<s1<<'\n';
}
}
}
int main(){
string s2="abc";
string s1="";
permute(s1,s2,s2.length());
return 0;
}
Your problem seems to be in the "smallString" function. In that function, OutOfRange is used in s[j]. I put print like
for(i=0,j=0;j<s.length();i++,j++)
{
if(i==k){j++;}
cout<<"smallString:: s ::"<<s<<'\t'<<"k::"<<k<<'\n';
res.push_back(s[j]); //Problem is here...
}
Now Output print is like
smallString:: s ::abc k::0
smallString:: s ::abc k::0
smallString:: s ::bc k::0
smallString:: s ::bc k::1
smallString:: s ::bc k::1
smallString:: s ::b k::0
smallString:: s ::b k::1
smallString:: s ::b k::1
.
.
So, At one point of time it comes as "s ::b k::1" so you are selecting the character at the position 1 from the string "b".
String is basically an char array which start from 0 to (n-1). For string "b" only 0th position is having character 'b'. but we are accessing an non-existing position.
So it throws error and start looping continuously from here.
FIX FOR YOUR ISSUE:
for(i=0,j=0;j<s.length();i++,j++)
{
if(i==k)
{
j++;
}
else
{
cout<<"smallString:: s ::"<<s<<'\t'<<"k::"<<k<<'\n';
res.push_back(s[j]);
}
}