const char * pointing to same memory location - c++

I am trying to break a string into integer and characters using below codes. in the first section on the immediate printing I got the right output but later it is wrong.
int Lottery::calcInvOdds(string ruleConstraint){
const char * sorted;
const char * unique;
string temp;
size_t pos;
temp = ruleConstraint;
pos = temp.find_first_of(" ");
sorted = temp.substr(0,pos).c_str();
cout << temp << endl;
cout << "S = " << sorted << endl;
temp = temp.substr(pos+1);
unique = temp.substr(0,pos).c_str();
cout << "U = " << unique << endl;
cout << "Sorted = " << sorted[0] << " " << "Unique = " << unique[0] << endl<<endl;
return 0;
}
Output is like this:
T F
S = T
U = F
Sorted = F Unique = F
F T
S = F
U = T
Sorted = T Unique = T
But after replacing const char * with array like char sorted[2] and temp.substr(0,pos).c_str(); with *temp.substr(0,pos).c_str(), Correct output was displayed. What is the reason of this behaviour?

sorted = temp.substr(0,pos).c_str();
This isn't going to work. temp.substr(0,pos) returns a temporary string, .c_str() gets a pointer to its contents, and after the statement completes the temporary string is freed, making sorted point to freed memory.
Your best option is to not even bother converting to const char* and instead change sorted and unique to be strings. Then things will work like you expect, because the strings will persist until the function exits.
int Lottery::calcInvOdds(const string& ruleConstraint){
size_t pos = ruleConstraint.find_first_of(" ");
string sorted = ruleConstraint.substr(0, pos);
// The above line could be rewritten as:
// string sorted(ruleConstraint, 0, pos);
cout << ruleConstraint << endl;
cout << "S = " << sorted << endl;
// -- Not sure this is what you want, but it's what your code does.
#if 1
string unique = ruleConstraint.substr(pos + 1, pos);
// -- maybe you meant this
#else
size_t pos2 = ruleConstraint.find_first_of(" ", pos + 1);
string unique(ruleConstraint, pos + 1, pos2 - pos - 1);
#endif
cout << "U = " << unique << endl;
cout << "Sorted = " << sorted[0] << " " << "Unique = " << unique[0] << endl << endl;
return 0;
}

Related

The result of the encrypted message after implementing RSA is 0 using the GMP library

I am using the GMP library functions in order to implement the RSA algorithm.
Here is my code:
const char* random_String() {
srand (time(NULL));
const char * tab[] = {"Alice", "Bob", "encryption", "decryption"};
std::cout << sizeof(tab)/sizeof(tab[0]) << std::endl;
int indice = rand() % (sizeof(tab)/sizeof(tab[0]));
return tab[indice];
}
int main()
{
mpz_init(d);
mpz_init(e);
mpz_init(n);
mpz_init(M);
mpz_init(c);
/* This function creates the keys. The basic algorithm is...
*
* 1. Generate two large distinct primes p and q randomly
* 2. Calculate n = pq and x = (p-1)(q-1)
* 3. Select a random integer e (1<e<x) such that gcd(e,x) = 1
* 4. Calculate the unique d such that ed = 1(mod x)
* 5. Public key pair : (e,n), Private key pair : (d,n)
*
*/
mpz_t p,q,op;
mpz_init(p);
mpz_init(q);
mpz_init(op);
char p_str[1000];
char q_str[1000];
mpz_init_set_str(op, "7060", 10);
mpz_nextprime(p, op);
mpz_get_str(p_str,10,p);
mpz_init_set_str(op, "7874", 10);
mpz_nextprime(q, op);
mpz_get_str(q_str, 10, q);
std::cout << "Random Prime 'p' = " << p_str << std::endl;
std::cout << "Random Prime 'q' = " << q_str << std::endl;
char n_str[1000];
mpz_t x;
mpz_init(x);
mpz_mul(n,p,q);
mpz_get_str(n_str,10,n);
std::cout << "\t n = " << n_str << std::endl;
mpz_t p_minus_1,q_minus_1;
mpz_init(p_minus_1);
mpz_init(q_minus_1);
mpz_sub_ui(p_minus_1,p,(unsigned long int)1);
mpz_sub_ui(q_minus_1,q,(unsigned long int)1);
mpz_mul(x,p_minus_1,q_minus_1);
char phi_str[1000];
mpz_get_str(phi_str,10,x);
std::cout << "\t phi(n) = " << phi_str << std::endl;
mpz_init_set_str(e, "79", 0);
char e_str[1000];
mpz_get_str(e_str,10,e);
std::cout << "\t e = " << e_str << std::endl;
mpz_invert(d, e, x);
char d_str[1000];
mpz_get_str(d_str,10,d);
std::cout << "\t d = " << d_str << std::endl << std::endl;
std::cout << "Public Keys (e,n): ( " << e_str <<" , " << n_str << " )" << std::endl;
std::cout << "Private Keys (d,n): ( " << d_str <<" , " << n_str << " )" << std::endl;
const char* mess = random_String();
char c_str[1000];
std::cout << "The message: : " << mess << std::endl;
mpz_set_str(M, mess, 10);
mpz_powm(c, M, e, n);
mpz_get_str(c_str, 10, c);
std::cout << "The encrypted message: " << c_str << std::endl;
}
During the last 5 lines of the code, I encrypt the message with the values that were previously computed and by following the RSA formulas of encryption.
The result of the encrypted message is 0, which means that the result of c_str is 0. How comes that it is 0?
This code
mpz_set_str(M, mess, 10);
converts the random string mess to an integer. For this to work the string must consist of decimal digits, but this is not true for any of your random strings. So the function fails and M is unchanged.
If you check the return value of mpz_set_str you will see that it is -1 meaning the function failed.
Basically your conversion to and from your message to an integer will only work if the message is a decimal number. To convert arbitrary strings you should be using the mpz_import and mpz_export functions instead of mpz_set_str and mpz_get_str.

Variable inside a loop being set to the next array's element has the same memory address all the time? [duplicate]

This question already has answers here:
Why is the address of a variable defined inside a loop unchanged on each iteration?
(3 answers)
Closed 2 years ago.
Let's consider a little program like this:
#include <iostream>
using namespace std;
typedef struct
{
int i, j, k;
} ThreeDPoint;
int main() {
ThreeDPoint p[10];
for (int i = 0; i < 10; i++) {
p[i].i = i * 3;
p[i].j = i * 3 + 1;
p[i].k = i * 3 + 2;
}
for (int i = 0; i < 10; i++) {
cout << "i = " << i << endl;
ThreeDPoint lp = p[i];
cout << "&p[" << i << "] = " << (long) &lp << endl;
cout << "&p[" << i << "].i = " << (long) &lp.i << endl;
cout << "p[" << i << "].i = " << (long) lp.i << endl;
cout << "&p[" << i << "].j = " << (long) &lp.j << endl;
cout << "p[" << i << "].j = " << (long) lp.j << endl;
cout << "&p[" << i << "].k = " << (long) &lp.k << endl;
cout << "p[" << i << "].k = " << (long) lp.k << endl;
}
}
Variable named lp is updated to have a value of a structure inside an array and being updated with the i variable inside the loop. I expect that if, for instance, first element (p[0]) starts at memory location 100, then the second element (p[1]) will start from 112, assuming that sizeof(int) == 4 is true.
It is not the case, though: the printed value informs that the variable is actually updated to contain the next structure value all the time, but it seems that it, for some reason, has the same memory address (for i = 0 &p[i].i == 100, for i = 1 &p[i].i == 100, too). What's interesting is that if the intermediate variable lp is removed and p[i] is accessed directly, then I see the expected memory addresses to be printed out (for i = 0 &p[i].i == 100, for i = 1 &p[i].i == 112). Here are the logs:
i = 0
&p[0] = 140736159721040
&p[0].i = 140736159721040
p[0].i = 0
&p[0].j = 140736159721044
p[0].j = 1
&p[0].k = 140736159721048
p[0].k = 2
i = 1
&p[1] = 140736159721040
&p[1].i = 140736159721040
p[1].i = 3
&p[1].j = 140736159721044
p[1].j = 4
&p[1].k = 140736159721048
p[1].k = 5
i = 2
&p[2] = 140736159721040
&p[2].i = 140736159721040
p[2].i = 6
&p[2].j = 140736159721044
p[2].j = 7
&p[2].k = 140736159721048
p[2].k = 8
Why is that? Why is the value updated but the memory location is the same? Is this some kind of g++ optimization that is performed after variables usage analysis?
You are printing the address of the variable, not the address of your array elements. The variable and the array don't have the same address (obviously) and it's quite reasonable (but not guaranteed) that the same address would be reused for the variable each time around the loop.
To print the address of the array element try this
cout << "&p[" << i << "] = " << &p[i] << endl;
I guess your misunderstanding is that you think
ThreeDPoint lp = p[i];
somehow makes lp point to the array element. But it doesn't, it copies the array element and stores a copy in the variable.

Is it possible to have memory problems that don’t crash a program?

I wrote a text cipher program. It seems to works on text strings a few characters long but does not work on a longer ones. It gets the input text by reading from a text file. On longer text strings, it still runs without crashing, but it doesn’t seem to work properly.
Below I have isolated the code that performs that text scrambling. In case it is useful, I am running this in a virtual machine running Ubuntu 19.04. When running the code, enter in auto when prompted. I removed the rest of code so it wasn't too long.
#include <iostream>
#include <string>
#include <sstream>
#include <random>
#include <cmath>
#include <cctype>
#include <chrono>
#include <fstream>
#include <new>
bool run_cypher(char (&a)[27],char (&b)[27],char (&c)[11],char (&aa)[27],char (&bb)[27],char (&cc)[11]) {
//lowercase cypher, uppercase cypher, number cypher, lowercase original sequence, uppercase original sequence, number original sequence
std::ifstream out_buffer("text.txt",std::ios::in);
std::ofstream file_buffer("text_out.txt",std::ios::out);
//out_buffer.open();
out_buffer.seekg(0,out_buffer.end);
std::cout << "size of text: " << out_buffer.tellg() << std::endl;//debug
const int size = out_buffer.tellg();
std::cout << "size: " << size << std::endl;//debug
out_buffer.seekg(0,out_buffer.beg);
char *out_array = new char[size + 1];
std::cout << "size of out array: " << sizeof(out_array) << std::endl;//debug
for (int u = 0;u <= size;u = u + 1) {
out_array[u] = 0;
}
out_buffer.read(out_array,size);
out_buffer.close();
char original[size + 1];//debug
for (int bn = 0;bn <= size;bn = bn + 1) {//debug
original[bn] = out_array[bn];//debug
}//debug
for (int y = 0;y <= size - 1;y = y + 1) {
std::cout << "- - - - - - - -" << std::endl;
std::cout << "out_array[" << y << "]: " << out_array[y] << std::endl;//debug
int match;
int case_n; //0 = lowercase, 1 = uppercase
if (isalpha(out_array[y])) {
if (islower(out_array[y])) {
//std::cout << "out_array[" << y << "]: " << out_array[y] << std::endl;//debug
//int match;
for (int ab = 0;ab <= size - 1;ab = ab + 1) {
if (out_array[y] == aa[ab]) {
match = ab;
case_n = 0;
std::cout << "matched letter: " << aa[match] << std::endl;//debug
std::cout << "letter index: " << match << std::endl;//debug
std::cout << "case_n: " << case_n << std::endl;//debug
}
}
}
if (isupper(out_array[y])) {
for (int cv = 0;cv <= size - 1;cv = cv + 1) {
if (out_array[y] == bb[cv]) {
case_n = 1;
match = cv;
std::cout << "matched letter: " << bb[match] << std::endl;//debug
std::cout << "letter index: " << match << std::endl;//debug
std::cout << "case_n: " << case_n << std::endl;//debug
}
}
}
if (case_n == 0) {
out_array[y] = a[match];
std::cout << "replacement letter: " << a[match] << " | new character: " << out_array[y] << std::endl;//debug
}
if (case_n == 1) {
std::cout << "replacement letter: " << b[match] << " | new character: " << out_array[y] << std::endl;//debug
out_array[y] = b[match];
}
}
if (isdigit(out_array[y])) {
for (int o = 0;o <= size - 1;o = o + 1) {
if (out_array[y] == cc[o]) {
match = o;
std::cout << "matched letter: " << cc[match] << std::endl;//debug
std::cout << "letter index: " << match << std::endl;//debug
}
}
out_array[y] = c[match];
std::cout << "replacement number: " << c[match] << " | new character: " << out_array[y] << std::endl;//debug
}
std::cout << "- - - - - - - -" << std::endl;
}
std::cout << "original text: " << "\n" << original << "\n" << std::endl;
std::cout << "encrypted text: " << "\n" << out_array << std::endl;
delete[] out_array;
return 0;
}
int main() {
const int alpha_size = 27;
const int num_size = 11;
char l_a_set[] = "abcdefghijklmnopqrstuvwxyz";
char cap_a_set[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char n_a_set[] = "0123456789";
std::cout << "sizeof alpha_set: " << std::endl;//debug
char lower[alpha_size] = "mnbvcxzasdfghjklpoiuytrewq";
char upper[alpha_size] = "POIUYTREWQASDFGHJKLMNBVCXZ";
char num[num_size] = "9876543210";
int p_run; //control variable. 1 == running, 0 == not running
int b[alpha_size]; //array with values expressed as index numbers
std::string mode;
int m_set = 1;
while (m_set == 1) {
std::cout << "Enter 'auto' for automatic cypher generation." << std::endl;
std::cout << "Enter 'manual' to manually enter in a cypher. " << std::endl;
std::cin >> mode;
std::cin.ignore(1);
std::cin.clear();
if (mode == "auto") {
p_run = 2;
m_set = 0;
}
if (mode == "manual") {
p_run = 3;
m_set = 0;
}
}
if (p_run == 2) { //automatic mode
std::cout <<"lower cypher: " << lower << "\n" << "upper cypher: " << upper << "\n" << "number cypher: " << num << std::endl;//debug
run_cypher(lower,upper,num,l_a_set,cap_a_set,n_a_set);
return 0;//debug
}
while (p_run == 3) {//manual mode
return 0;//debug
}
return 0;
}
For example, using an array containing “mnbvcxzasdfghjklpoiuytrewq” as the cipher for lower case letters, I get “mnbv” if the input is “abcd”. This is correct.
If the input is “a long word”, I get “m gggz zzzv” as the output when it should be “m gkjz rkov”. Sort of correct but still wrong. If I use “this is a very very long sentence that will result in the program failing” as the input, I get "uas” as the output, which is completely wrong. The program still runs but it fails to function as intended. So as you can see, it does work, but not on any text strings that are remotely long. Is this a memory problem or did I make horrible mistake somewhere?
For your specific code, you should run it through a memory checking tool such as valgrind, or compile with an address sanitizer.
Here are some examples of memory problems that most likely won't crash your program:
Forgetting to delete a small object, which is allocated only once in the program. A memory leak can remain undetected for decades, if it does not make the program run out of memory.
Reading from allocated uninitialized memory. May still crash if the system allocates objects lazily at the first write.
Writing out of bounds slightly after an object that sits on heap, whose size is sizeof(obj) % 8 != 0. This is so, since heap allocation is usually done in multiples of 8 or 16. You can read about it at answers of this SO question.
Dereferencing a nullptr does not crash on some systems. For example AIX used to put zeros at and near address 0x0. Newer AIX might still do it.
On many systems without memory management, address zero is either a regular memory address, or a memory mapped register. This memory can be accessed without crashing.
On any system I have tried (POSIX based), it was possible to allocate valid memory at address zero through memory mapping. Doing so can even make writing through nullptr work without crashing.
This is only a partial list.
Note: these memory problems are undefined behavior. This means that even if the program does not crash in debug mode, the compiler might assume wrong things during optimization. If the compiler assumes wrong things, it might create an optimized code that crashes after optimization.
For example, most compilers will optimize this:
int a = *p; // implies that p != nullptr
if (p)
boom(p);
Into this:
int a = *p;
boom(p);
If a system allows dereferencing nullptr, then this code might crash after optimization. It will not crash due to the dereferencing, but because the optimization did something the programmer did not foresee.

How can I get the size of a vector that is inside another vector?

I'm having trouble getting the size of a vector by dot-walking from a parent vector into the one in question. I have verified that calling the function myfunc 1 2 3 4 5 creates five Person objects and puts them in the left vector. But when I try to get that same size to return by dot-walking from bridge to left, I get 0 as the size.
What am I doing wrong?
int main(int argc, char* argv[]) {
Person* p_ptr;
int id_source = 0;
vector<Person> left;
vector<Person> right;
bridge.push_back(left);
bridge.push_back(right);
cout << "bridge.size() = " << bridge.size() << endl;
for (int i = 1; i < argc; i++) {
id_source++;
cout << "Creating Person with crossing speed of " << argv[i] << " and id of " << id_source << endl;
p_ptr = new Person(atoi(argv[i]), id_source);
left.push_back(*p_ptr);
}
/*SIZE TESTING*/
cout << "Left side of bridge has " << left.size() << " people on it " << endl;
cout << "bridge.at(0).size() = " << bridge.at(0).size() << endl;
cout << "bridge.at(1).size() = " << bridge.at(1).size() << endl;
int slowest_id = get_slowest(0);
for (int i = 0; i < left.size(); i++) {
if (slowest_id == left.at(i).get_id()) {
p_ptr = &left.at(i);
}
}
cout << "The slowest person has id of " << slowest_id << " and speed of " << p_ptr->get_crossing_time() << endl;
}
}
left and bridge[0] are two different lists. When you call bridge.push_back(left) you make a copy of the current left list (which is empty). Elements added later will not be in the bridge version.

getting bus error : 10 with string append

I have a function that takes two strings and determines if they are the same. I am trying to tokenize the string and combine all of tokens into one string. This is what I have so far and I am getting Bus error :10.
any help appreciated.
#include <iostream>
#include <string>
using namespace std;
bool stringCheck(string s1, string s2){
string strCheck1 = "";
string strCheck2 = "";
char *cstr1 = new char[s1.length()]; // char array with length of string
strcpy(cstr1, s1.c_str()); // copies characters of string to char array
char *cstr2 = new char[s2.length()];
strcpy(cstr2, s2.c_str());
char *p1 = strtok(cstr1, " "); // creates a char array that stores token that
// is delimeted
cout << "p1 " << p1 << endl; ///outputs token that is found
strCheck1.append(p1); // appends token to string
cout << "strCheck1 " << strCheck1 << endl; // outputs string
while(p1 != NULL) // while the token is not a null character
{
cout<<"parsing" << endl;
p1 = strtok(NULL, " "); // continue to parse current string.
cout << "p1 " << p1 << endl;
strCheck1.append(p1);
cout << "str1 " << strCheck1 << endl;
}
char * p2 = strtok(cstr2, " ");
cout << "p2 " << p2 << endl;
strCheck2.append(p2);
cout << "strCheck2 " << strCheck2 << endl;
while(p2 != null){
p2 = strtok(NULL, " ");
strCheck2.append(p2);
cout << "str2 " << strCheck2 << endl;
}
if( strCheck1.compare(strCheck2) != 0)
{
return 0;
}
else return 1;
}
int main(void){
string s1 = "jam yoooo jay";
string s2 = "jam yoooo";
if(stringCheck(s1, s2) == 1){
cout << "strings same"<< endl;;
}
else{
cout << "strings not same" << endl;
}
}
is there a conditional statement I could pair up with
while(p1 != NULL)
I know this is a pretty silly function but just trying to polish up my skills. any help appreciated!
There are some things you must change:
char *cstr1 = new char[s1.length()];
c-string are null-terminated, so you need one more char to store the null character:
char *cstr1 = new char[s1.length() + 1];
(same for cstr2)
strCheck1.append(p1)
p1 cannot be a null pointer (see Assign a nullptr to a std::string is safe? for further details). So you have to check...
if (p1) strCheck1.append(p1);
(same for p2).
cout << p1 << endl
if p1 is a null pointer bad things can happen (see Why does std::cout output disappear completely after NULL is sent to it). So you have to check...
if (p1) { cout << "p1 " << p1 << endl; strCheck1.append(p1); }
(same for p2)
there is a memory leak (cstr1 / cstr2 must be deleted).
At the end it should work.
Probably you should consider other systems to extract tokens (where you haven't to mix std::string and c-string). E.g.:
#include <iostream>
#include <string>
#include <sstream>
int main()
{
std::string text("text-to-tokenize");
std::istringstream iss(text);
std::string token;
while(getline(iss, token, '-'))
std::cout << token << std::endl;
return 0;
}