Confusing of "Access Violation " - c++

I don't Understand with this case but this is really really important for me, Please Help me...
void __fastcall TForm1::Button4Click(TObject *Sender)
{
String masuk, keluar, kosong;
int i, x, j, n = 0;
masuk = Edit2->Text;
keluar = masuk;
kosong = " ";
n = 0;
x = 0;
mulai:
i = 1;
j = 0;
j = j + n;
i = i + j;
if (masuk[i] == 'a')
{
keluar[i] = 't';
}
else if (masuk[i] == 't')
{
keluar[i] = 'a';
}
else if (masuk[i] == 'c')
{
keluar[i] = 'g';
}
else if (masuk[i] == 'g')
{
keluar[i] = 'c';
}
else
{
Application->MessageBoxA("Masukan Anda Salah", "Peringatan", MB_OK | MB_ICONWARNING);
keluar = kosong;
goto end;
}
n = n + 1;
if (i < 10)
goto mulai;
else
goto end;
end:
Memo1->Text = keluar;
}
if I make masukan more than 10 (i<10 (10 as default value)), it is ok but if it less than 10, it will make message exception Class EAccessViolation..

Taking a shot in the dark, but I think what you're actually trying to do might be this. I'm assuming that you're taking a single string of 10 characters which represents one half of a genome and you're generating another string of the pair values.
void __fastcall TForm1::Button4Click(TObject *Sender)
{
String masuk, keluar;
masuk = Edit2->Text;
keluar = masuk;
char kosong = ' ';
for (int i=0; i < 10; i++)
{
switch(masuk[i]) {
case 'a':
keluar[i] = 't';
break;
case 't':
keluar[i] = 'a';
break;
case 'c':
keluar[i] = 'g';
break;
case 'g':
keluar[i] = 'c';
break;
default:
Application->MessageBoxA("Masukan Anda Salah", "Peringatan", MB_OK | MB_ICONWARNING);
keluar[i] = kosong;
break;
}
Memo1->Text = keluar;
}

Related

Stack smashing detected

#include <iostream>
using namespace std;
int main()
{
int tablica[9];
string inputromanum;
cout << "ROMAN: ";
cin >> inputromanum;
int maxindeks;
bool disablenextcomp = false;
int readysolution = 0;
maxindeks = inputromanum.length() - 1;{}{}
for (int i = 0; i <= maxindeks; i++)
{
if (inputromanum[i] == 'M' || inputromanum[i] == 'm')
{
tablica[i] = 1000;
}
if (inputromanum[i] == 'D' || inputromanum[i] == 'd')
{
tablica[i] = 500;
}
if (inputromanum[i] == 'C'|| inputromanum[i] == 'c')
{
tablica[i] = 100;
}
if (inputromanum[i] == 'L' || inputromanum[i] == 'l')
{
tablica[i] = 50;
}
if (inputromanum[i] == 'X' || inputromanum[i] == 'x')
{
tablica[i] = 10;
}
if (inputromanum[i] == 'V' || inputromanum[i] == 'v')
{
tablica[i] = 5;
}
if (inputromanum[i] == 'I' || inputromanum[i] == 'i')
{
tablica[i] = 1;
}
}
cout<<endl;
for(int i4 = 0; i4 <= maxindeks; i4++)
{
cout<<"tablica["<<i4<<"] = "<<tablica[i4]<<endl;
}
for (int i2 = 0; i2 <= maxindeks; i2++)
{
int i5 = i2 + 1;
if (i5 <= maxindeks)
{
//cout<<endl<<"tablica[i2 + 1] = "<<tablica[i2 + 1];
//cout<<endl<<"tablica[i2] = "<<tablica[i2];
//cout<<endl<<"tablica[i2 + 1] - tablica[i2] = "<<tablica[i2 + 1] - tablica[i2];
if (tablica[i2 + 1] - tablica[i2] > 0 && disablenextcomp == false)
{
//cout<<endl<<"readysolution + (tablica[i2 + 1] - tablica[i2]) = "<<readysolution + (tablica[i2 + 1] - tablica[i2])<<endl;
readysolution = readysolution + (tablica[i2 + 1] - tablica[i2]);
disablenextcomp = true;
}
else
{
if(disablenextcomp == false)
{
//cout<<endl<<"readysolution + tablica[i2] = "<<readysolution + tablica[i2]<<endl;
readysolution = readysolution + tablica[i2];
}
else
{
disablenextcomp = false;
}
}
}
else
{
if(disablenextcomp == false)
{
//cout<<endl<<endl<<"OSTATNI INDEKS";
//cout<<endl<<"tablica[i2] = "<<tablica[i2];
//cout<<endl<<"readysolution + tablica[i2] = "<<readysolution + tablica[i2];
readysolution = readysolution + tablica[i2];
}
}
i5++;
}
cout << endl << readysolution;
}
This is my program. made for decoding roman numerals into arabic ones. It works as intended in most cases, however, one of my colleagues found it to produce this error while inputting MMMCMXCVIII into the program:
*** stack smashing detected ***: terminated
It would refuse to work afterwards.
I wasn't able to find different numbers that would cause this error except MMMMMMMMMMM.
It seems to fail when the index of tablica array exceeds 10. I don't know why it does so, as i am a novice in c++. It should've outputted 3999 instead of the error appearing. The numbers it should process successfully should range from 1 to 5000.
Thanks to folks in the comments, I've found the cause.
The tablica[9] array is supposed to store 9 or less characters.
The length of the input (MMMCMXCVIII in this case) has more characters, therefore it makes the for loop responsible for storing values for each character to cause mentioned above error, as there are no remaining units to store the values in.
I've expanded the storage of tablica to 25 characters.
In modern C++ it is considered bad practice to use C-style arrays and index loops whenever you can avoid this. So, fo example you can rewrite first loop like this:
std::vector<int> tablica;
tablica.reserve(inputromanum.size()); // This line is not necessary, but it can help optimize memory allocations
for (char c : inputromanum)
{
if (c == 'M' || c == 'm')
{
tablica.push_back(1000);
}
if (c == 'D' || c == 'd')
{
tablica.push_back(500);
}
if (c == 'C'|| c == 'c')
{
tablica.push_back(100);
}
if (c == 'L' || c == 'l')
{
tablica.push_back(50);
}
if (c == 'X' || c == 'x')
{
tablica.push_back(10);
}
if (c == 'V' || c == 'v')
{
tablica.push_back(5);
}
if (c == 'I' || c == 'i')
{
tablica.push_back(1);
}
}
And you will avoid your issue completly. Something similar can be done with other loops too. This approach also has benefit of (somewhat) properly handling situations when input line has other symbols, which is not roman number. Try it on your version and you will see what I mean.
One more point. When you need to do something different depending of value of one variable, like you did with all those ifs. There is special statement in C/C++ for this: switch. So instead of those ifs you can do this:
std::vector<int> tablica;
tablica.reserve(inputromanum.size()); // This line is not necessary, but it can help optimize memory allocations
for (char c : inputromanum)
{
switch(c)
{
case 'M':
case 'm':
tablica.push_back(1000);
break;
case 'D':
case 'd':
tablica.push_back(500);
break;
case 'C':
case 'c':
tablica.push_back(100);
break;
case 'L':
case 'l':
tablica.push_back(50);
break;
case 'X':
case 'x':
tablica.push_back(10);
break;
case 'V':
case 'v':
tablica.push_back(5);
break;
case 'I':
case 'i':
tablica.push_back(1);
break;
}
}

Turn if else into a for loop

I want to choose positions 1, 3, 7, 9.
I made an if else statement that solves the problem. Could this be implemented in a for loop.
int move1 = (rand() % 4) + 1;
if (move1 == 1)
{
move1 = 1;
}
else if (move1 == 2)
{
move1 = 3;
}
else if (move1 == 3)
{
move1 = 7;
}
else if (move1 == 4)
{
move1 = 9;
}
I don't know about a loop, but usually you want to implement these kind of things with a switch statement. Something like this:
int move1;
switch(rand() % 4)
{
case 1:
move1 = 1;
break;
case 2:
move1 = 3;
break;
case 3:
move1 = 7;
break;
case 4:
move1 = 9;
break;
}

RNA to protein. Program compiles but won't stop running

I recently learned about multidimensional arrays and was given the task of analyzing strands of RNA and translating them into sequences of protein. I decided to use my knowledge of multidimensional arrays to create a definition of each amino acid a codon (group of 3 RNA bases) would translate to.
//RNA codon to amino acid mapping
char aminoAcid[4][4][4];
//A = 0, C = 1, G = 2, U = 3
//phenylalanine - F
aminoAcid[3][3][3] = 'F';
aminoAcid[3][3][1] = 'F';
//Leucine - L
aminoAcid[3][3][0] = 'L';
aminoAcid[3][3][2] = 'L';
//Serine - S
aminoAcid[3][1][3] = 'S';
aminoAcid[3][1][1] = 'S';
aminoAcid[3][1][0] = 'S';
aminoAcid[3][1][2] = 'S';
//tyrosine - Y
aminoAcid[3][0][3] = 'Y';
aminoAcid[3][0][1] = 'Y';
//stop codon
aminoAcid[3][0][0] = '-';
aminoAcid[3][0][2] = '-';
//cysteine - C
aminoAcid[3][2][3] = 'C';
aminoAcid[3][2][1] = 'C';
//stop codon
aminoAcid[3][2][0] = '-';
//tryptophan - W
aminoAcid[3][2][2] = 'W';
//leucine - L
aminoAcid[1][3][3] = 'L';
aminoAcid[1][3][1] = 'L';
aminoAcid[1][3][0] = 'L';
aminoAcid[1][3][2] = 'L';
//proline - P
aminoAcid[1][1][3] = 'P';
aminoAcid[1][1][1] = 'P';
aminoAcid[1][1][0] = 'P';
aminoAcid[1][1][2] = 'P';
//histidine - H
aminoAcid[1][0][3] = 'H';
aminoAcid[1][0][1] = 'H';
//glutamine - Q
aminoAcid[1][0][0] = 'Q';
aminoAcid[1][0][2] = 'Q';
//arginine - R
aminoAcid[1][2][3] = 'R';
aminoAcid[1][2][1] = 'R';
aminoAcid[1][2][0] = 'R';
aminoAcid[1][2][2] = 'R';
//isoleucine - I
aminoAcid[0][3][3] = 'I';
aminoAcid[0][3][1] = 'I';
aminoAcid[0][3][0] = 'I';
//methionine(start codon) - M
aminoAcid[0][3][2] = 'M';
//threonine -T
aminoAcid[0][1][3] = 'T';
aminoAcid[0][1][1] = 'T';
aminoAcid[0][1][0] = 'T';
aminoAcid[0][1][2] = 'T';
//asparagine - N
aminoAcid[0][0][3] = 'N';
aminoAcid[0][0][1] = 'N';
//lysine - K
aminoAcid[0][0][0] = 'K';
aminoAcid[0][0][2] - 'K';
//serine - S
aminoAcid[0][2][3] = 'S';
aminoAcid[0][2][1] = 'S';
//arginine - R
aminoAcid[0][2][0] = 'R';
aminoAcid[0][2][2] = 'R';
//valine - V
aminoAcid[2][3][3] = 'V';
aminoAcid[2][3][1] = 'V';
aminoAcid[2][3][0] = 'V';
aminoAcid[2][3][2] = 'V';
//alanine - A
aminoAcid[2][1][3] = 'A';
aminoAcid[2][1][1] = 'A';
aminoAcid[2][1][0] = 'A';
aminoAcid[2][1][2] = 'A';
//aspartic acid - D
aminoAcid[2][0][3] = 'D';
aminoAcid[2][0][1] = 'D';
//glutamic acid - E
aminoAcid[2][0][0] = 'E';
aminoAcid[2][0][2] = 'E';
//glycine - G
aminoAcid[2][2][3] = 'G';
aminoAcid[2][2][1] = 'G';
aminoAcid[2][2][0] = 'G';
aminoAcid[2][2][2] = 'G';
I created the following function to translate the strand. In this case, please note that my rna strand is:
AUGCUUAUUAACUGAAAACAUAUGGGUAGUCGAUGA
string rnaAnalysis::translateRna()
{
string protein = "";
int firstBase, secondBase, thirdBase;
for(int i = 0; i < newSequence.length() - 2; i+3)
{
if(newSequence[i] == 'A')
{
firstBase = 0;
}
else if(newSequence[i] == 'C')
{
firstBase = 1;
}
else if(newSequence[i] == 'G')
{
firstBase = 2;
}
else if(newSequence[i] == 'U')
{
firstBase = 3;
}
if(newSequence[i+1] == 'A')
{
secondBase = 0;
}
else if(newSequence[i+1] == 'C')
{
secondBase = 1;
}
else if(newSequence[i+1] == 'G')
{
secondBase = 2;
}
else if(newSequence[i+1] == 'U')
{
secondBase = 3;
}
if(newSequence[i+2] == 'A')
{
thirdBase = 0;
}
else if(newSequence[i+2] == 'C')
{
thirdBase = 1;
}
else if(newSequence[i+2] == 'G')
{
thirdBase = 2;
}
else if(newSequence[i+2] == 'U')
{
thirdBase = 3;
}
bool readSequence = true;
if (aminoAcid[firstBase][secondBase][thirdBase] == aminoAcid[0][3][2])
{
readSequence = true;
}
else if (aminoAcid[firstBase][secondBase][thirdBase] == aminoAcid[3][0][0] ||
aminoAcid[firstBase][secondBase][thirdBase] == aminoAcid[3][0][2] ||
aminoAcid[firstBase][secondBase][thirdBase] == aminoAcid[3][2][0])
{
readSequence = false;
}
if(readSequence)
{
protein = protein + aminoAcid[firstBase][secondBase][thirdBase] + " ";
}
else
{
continue;
}
}
return protein;
}
The bool is used for "start codons" and "stop codons", basically codons within the strand that will tell you when to record and when to stop. newSequence would be the RNA strand.
EDIT: I'm fairly new at this, so I understand my code may look really ugly. Any feedback on how to clean it up is much appreciated as well.
for(int i = 0; i < newSequence.length() - 2; i+3)
should be
for(int i = 0; i < newSequence.length() - 2; i += 3)
Your code never changes the value of i which is why it never stops running.
Your loop starts with the same piece of code three times, where you convert the letter to the 'base index'. That's an obvious place to use a function
for (int i = 0; i < newSequence.length() - 2; i += 3)
{
int firstBase = baseIndex(newSequence[i]);
int secondBase = baseIndex(newSequence[i + 1]);
int thirdBase = baseIndex(newSequence[i + 2]);
...
I'll leave you to write the baseIndex function.

qt multiple keys in keypressevent()

I'm trying to create a game on Qt where the player can go diagonally. So when I press W and D, the player can go to the upper right hand corner. However, when I press W first, then D, then release D, the player does not go in the W direction. In fact, the holding of the W key isn't even being signaled to call the keypressevent() function.
However, when I press W, then D, and then release W, the character goes in the D direction.
Here are my codes:
void my_qscroll::keyPressEvent(QKeyEvent *event)
{
switch ( event->key() )
{
case Qt::Key_W:
key[0] = 1;
break;
case Qt::Key_A:
key[1] = 1;
break;
case Qt::Key_S:
key[2] = 1;
break;
case Qt::Key_D:
key[3] = 1;
break;
}
for(int i = 0; i != 4 ; i++)
{
if(key[i] == 1)
{
this->B = i;
emit Move();
}
}
}
void my_qscroll::keyReleaseEvent(QKeyEvent *event)
{
switch ( event->key() )
{
case Qt::Key_W:
key[0] = 0;
qDebug() << "released W";
break;
case Qt::Key_A:
key[1] = 0;
qDebug() << "released A";
break;
case Qt::Key_S:
key[2] = 0;
qDebug() << "released S";
break;
case Qt::Key_D:
key[3] = 0;
qDebug() << "released D";
break;
}
}
I'm not sure how to proceed through this problem. Any ideas or links to help me would be great. Thank you in advance.
You would need something like this:
void my_qscroll::keyPressEvent(QKeyEvent *event)
{
switch ( event->key() )
{
case Qt::Key_W:
key[0] = 1;
break;
case Qt::Key_A:
key[1] = 1;
break;
case Qt::Key_S:
key[2] = 1;
break;
case Qt::Key_D:
key[3] = 1;
break;
}
for(int i = 0; i != 4 ; i++)
{
if(key[i] == 1)
{
this->B = i;
emit Move();
}
}
}
void my_qscroll::keyReleaseEvent(QKeyEvent *event)
{
switch ( event->isAutoRepeat() )
{
case Qt::Key_W:
key[0] = 0;
qDebug() << "released W";
break;
case Qt::Key_A:
key[1] = 0;
qDebug() << "released A";
break;
case Qt::Key_S:
key[2] = 0;
qDebug() << "released S";
break;
case Qt::Key_D:
key[3] = 0;
qDebug() << "released D";
break;
}
}
void my_qscroll::movePlayer() {
if (key[1] && key[0]) {
left -= 2;
top -= 2;
} else if (key[3] && key[0]) {
left += 2;
top -= 2;
} else if (key[2] && key[1]) {
left -= 2;
top += 2;
} else if (key[2] && key[3]) {
left += 2;
top += 2;
} else if (key[3]) {
left += 2;
} else if (key[1]) {
left -= 2;
} else if (key[2]) {
top += 2;
} else if (key[0]) {
top -= 2;
}
}
void myCanvas::updateEnv() {
emit Move();
repaint();
}

Poker code cleanup modification from book...not quite right

Working through more book examples- this one is a partial poker program-
This segment deals with straight hand....
First what was given- only relevant parts....will provide entire code if needed...
int suits[5]; //index 1..4- value start at 1
int values[14]; //index 1..13- value same as rank, A = 1, K = 13
cin.get(rankCh);
switch (toUpper(rankCh)) {
case 'A': values = 1; break;
case '2': values = 2; break;
case '3': values = 3; break;
case '4': values = 4; break;
case '5': values = 5; break;
case '6': values = 6; break;
case '7': values = 7; break;
case '8': values = 8; break;
case '9': values = 9; break;
case 'T': values = 10; break;
case 'J': values = 11; break;
case 'Q': values = 12; break;
case 'K': values = 13; break;
default:
badCard = true;
}
Other functions:
bool isFlush(int suits[]) {
for(i = 1; i <= 4; i++)
if (suits[i] == 5) //5 here is Number of Cards
return true;
return false;
}
Yeah, I know about the array declarations but that is how it is defined- nice justification for it in the text...starting to number at 1
I want my straight hand to handle both Ace high and low- right now as define above aces are low...
Two versions: 1st appears not sure correct with low aces...
CODE
bool isStraight(int values[]) //Version one only straight- low aces only
{
int count = 0;
for (i = 1; i <= 13; i++) {
if (values[i] != 1) {
count++;
} else
count = 0;
if (count == 5) //5 is NUMCARDS
return true;
}
return false;
}
Now this is the where I need some recommendation: to have a function to handle both ace high and low:
bool isStraight(int values[]) //Version handles both high and low
{
int count = 0;
for (i = 1; i <= 13; i++) {
if (values[i] != 1) {
count++;
// if(i == 1 && values[1] != 0) //Check for high and low
// count++;
} else
count = 0;
if (count == 5) //5 is NUMCARDS
return true;
}
return false;
}
Would what I have in comments work to handle both ace high and low...
Since i = 1 is represented as ace and not sure what values[1] is correct should it be values[13] or what...maybe something like
if (i == 1)
values[13] //not sure...
Recommendations-
do not want wholesale changes- just to have minor changes with what I have...I do not want to sort or solve by brute force i.e like values[1] == 1 && values [2] ==1 you get the point- the text does that already but I am trying to rewrite it this way...
Thanks...Hope I am getting across my modification I would like...
EDIT: I figured I'd would first answer your question directly. Lets first clear up how the original algorithm worked. Basically it loops from 1 to 13, and each time it sees a card in that slot, it adds to count. If anything ever breaks the sequence, it resets the counter. Finally, if the counter reaches 5, you have a straight.
I can't say off hand if your solution would work, I say give it a go. However, a simple quick patch to the original would probably go something like this:
//Version handles both high and low
bool isStraight(int values[]) {
int count = 0;
for (i = 1; i <= 13; i++) {
if (values[i] != 1) {
count++;
} else
count = 0;
if (count == 5) //5 is NUMCARDS
return true;
}
// handle ace high.
if(count == 4 && values[1] != 0) {
return true;
}
return false;
}
Basically what that does is say "if we already have 4 in a row, and we've just looked at the very last card (the loop is over), then check an ace is there, if so, we do have a straight and it is ace high".
ORIGINAL ANSWER:
I think the easiest way to handle ace high and low is to have the "get rank" function have two modes, one which returns ace high, the other which returns ace low. Then just calculate the hand value for each case and take the better one.
Also, your get rank could be way simpler :-P.
int get_rank(char card) {
static const char *cards = "A23456789TJQK";
char *p = strchr(cards, toupper(card));
if(p) {
return (p - cards) + 1;
} else {
return -1;
}
}
so if you want to have a get_rank which has an ace_high or an ace_low, you could do this:
int get_rank(char card, bool ace_high) {
static const char *cards_high = "23456789TJQKA";
static const char *cards_low = "A23456789TJQK";
const char *cards = ace_high ? cards_high : cards_low;
char *p = strchr(cards, toupper(card));
if(p) {
return (p - cards) + 1;
} else {
return -1;
}
}
EDIT:
for fun, i've made a quick and dirty program which detects straights (handling both high and low ace). It is fairly simple, but could be shorter (also note that there is no attempt at buffer safety with these arrays, something of production quality should use something safer such as std::vector:
#include <algorithm>
#include <iostream>
#include <cstring>
int get_rank(char card, bool ace_high) {
static const char *cards_high = "23456789TJQKA";
static const char *cards_low = "A23456789TJQK";
const char *cards = ace_high ? cards_high : cards_low;
char *p = strchr(cards, toupper(card));
if(p) {
return (p - cards) + 1;
} else {
return -1;
}
}
bool is_rank_less_low(int card1, int card2) {
return get_rank(card1, false) < get_rank(card2, false);
}
bool is_rank_less_high(int card1, int card2) {
return get_rank(card1, true) < get_rank(card2, true);
}
bool is_straight(int hand[], bool ace_high) {
std::sort(hand, hand + 5, ace_high ? is_rank_less_high : is_rank_less_low);
int rank = get_rank(hand[0], ace_high);
for(int i = 1; i < 5; ++i) {
int new_rank = get_rank(hand[i], ace_high);
if(new_rank != rank + 1) {
return false;
}
rank = new_rank;
}
return true;
}
bool is_straight(int hand[]) {
return is_straight(hand, false) || is_straight(hand, true);
}
int main() {
int hand1[5] = { 'T', 'J', 'Q', 'K', 'A' };
int hand2[5] = { 'A', '2', '3', '4', '5' };
std::cout << is_straight(hand1) << std::endl;
std::cout << is_straight(hand2) << std::endl;
}
The case where an ace-high straight exists can be found by changing the final test:
if (count == 5 || count == 4 && values[1] == 1) // 2nd case handles ace-high straight
return true;
It's a special case, so it must be handled separately.