elements of a pointer array unreachable when passed to a function - c++

I cannot print the values of a character array, even when I pass the array with the address of its first element:
vbv_packet = Packet::create(&username[0],
&password[0], Packet::VBV, Packet::DATA,
bytea_from_memptr(& new_mr, car_multirecord::HEADER_SIZE +
(new_mr.get_count() * sizeof(car_compact_record))));
And in the definition function I try to print the array values like this:
static Packet::ptr create(const char* username, const char* password,RTCINET_COMMANDS cmd, RTCINET_COMMANDS subcmd, Packet::ptr_bytea ba)
// TODO: unsigned short command_seq, data_seq, length
{
//Add user authentication fields, username n password here
std::cout << "********** CREATING PACKET";
std::cout << "sizeof username: " << strlen(username);
std::cout << "sizeof password: " << strlen(password);
for(int i = 0; i < strlen(username); i++)
{
std::cout << *(username + sizeof(char) * i);
}
std::cout << "\n";
for(int j = 0; j < strlen(password); j++)
{
std::cout << password[j];
}
needless to say, the two string are defined as:
const char username[] = "ARG-CO";
const char password[] = "xxxxx!";
where am I doing wrong?

vbv_packet = Packet::create(username,
password, Packet::VBV, Packet::DATA,
bytea_from_memptr(& new_mr, car_multirecord::HEADER_SIZE +
(new_mr.get_count() * sizeof(car_compact_record))));
Should be correct, what are you trying to achieve here:
for(int i = 0; i < strlen(username); i++)
{
std::cout << *(username + sizeof(char) * i);
}
Why are you doing this *(username + sizeof(char) * i), If you wanna print every character in this char array use it like this : username[i]
Is it printing the password correctly?

Related

How do I convert long doubles to char arrays?

I am running a C++ program to sort strings as numbers.
I am saving strings in a char array vector but want to sort numbers as numbers so I am converting number strings into long doubles by calling "tonum()" then converting them back to strings when I am done by calling "tostring()". I am calling "numstr()" strictly for readability and debugging. I convert numbers 0 through 7 and the 6th number across for each value changes every time I run it. In my actual program, the first 5 numbers also seem to change. How do I get consistent results for a long double so that I can properly sort long doubles in char arrays?
#include<iostream>
std::string::size_type sz;
//___________________________________________________
std::string tonum(std::string str)
{
const int len = sizeof(long double);
std::string out = "0000000000000000";
union
{
long double dbl;
char array[len];
};
try
{
dbl = stold(str);
}
catch(std::exception &err)
{
dbl = 0;
}
for (int i = 0; i < len; i++)
{
std::cout << (int)array[i] << "\n";
out[len-i-1] = array[i];
}
return(out);
}
//___________________________________________________
std::string fromnum(std::string str)
{
const int len = sizeof(long double);
std::string out = "";
union
{
long double dbl;
char array[len];
};
for (int i = 0; i < len; i++)
{
array[len-i-1] = str[i];
}
out = std::to_string(dbl);
return(out);
}
//_____________________________________________________
std::string numstr(std::string str)
{
std::string out = fromnum(str) + ":";
for (int i = 0; i < str.length(); i++)
{
std::string look = std::to_string(str[i]);
int lookint = stold(look,&sz);
if (lookint < 0) lookint += 256;
std::string look2 = std::to_string(lookint);
out += look2 + " ";
}
return(out);
}
//_____________________________________________________
int main()
{
std::cout << numstr(tonum("0")) << "\n";
std::cout << numstr(tonum("1")) << "\n";
std::cout << numstr(tonum("2")) << "\n";
std::cout << numstr(tonum("3")) << "\n";
std::cout << numstr(tonum("4")) << "\n";
std::cout << numstr(tonum("5")) << "\n";
std::cout << numstr(tonum("6")) << "\n";
std::cout << numstr(tonum("7")) << "\n";
}
//_____________________________________________________

segmentation fault when trying to read values from dynamically allocated 2-D array c++ and gives munmap_chunk(): when trying to delete it

I'm trying to measure the time taken for insertion sort (avg, best, and worst for certain a size, n times) and storing all results in a 2D array
Here is the code for it:
#include <iostream>
#include <sys/time.h>
void insertionSort(int* array, int size) {
for (int i = 1; i < size; i++) {
std::cout << "insetion flag " << i << std::endl;
int key = array[i];
int j = i - 1;
while (key < array[j] && j >= 0) {
array[j + 1] = array[j];
j--;
}
array[j + 1] = key;
}
}
void getRandomArray(int* avg, int* best, int* worst, int size) {
srand((unsigned)time(0));
for (int i = 0; i < size; i++) {
//std::cout << "rand flag " << i << std::endl;
avg[i] = (rand() % 100) + 1;
}
for (int i = 0; i < size; i++) {
//std::cout << "copy flag " << i << std::endl;
best[i] = avg[i];
}
insertionSort(best, size);
for (int i = 0, j = size; i < size; i++, j--) {
//std::cout << "rev flag " << i << std::endl;
worst[j] = best[i];
}
}
double getComplx(int* arry, int size) {
struct timeval *start, *end;
std::cout << "comp flag " << std::endl;
gettimeofday(start, NULL);
insertionSort(arry, size);
gettimeofday(end, NULL);
double timeTaken = (end->tv_sec - start->tv_sec) * 1000000 + (end->tv_usec - start->tv_usec);
return timeTaken;
}
int main(int argc, char** argv) {
int size = atoi(argv[1]);
int times = atoi(argv[2]);
int* avg = new int[size];
int* best = new int[size];
int* worst = new int[size];
double** resTable = new double*[times];
for (int i = 0; i < times; i++) {
std::cout << i << std::endl;
resTable[i] = new double[3];
}
std::cout << "flag 1" << std::endl;
for (int i = 0; i < times; i++) {
getRandomArray(avg, best, worst, size);
std::cout << "flag 2" << std::endl;
resTable[i][0] = getComplx(avg, size);
std::cout << " avg ("<<i<<") (0) " << resTable[i][0] << std::endl;
resTable[i][1] = getComplx(best, size);
std::cout << " best ("<<i<<") (0) " << resTable[i][1] << std::endl;
resTable[i][2] = getComplx(worst, size);
std::cout << " worst ("<<i<<") (0) " << resTable[i][2] << std::endl;
printf("|%9.0f |%9.0f |%9.0f |", resTable[i][0], resTable[i][1], resTable[i][2]);
std::cout << " : loop no : " << i << std::endl;
}
std::cout << "after loop" << std::endl;
delete []avg;
std::cout << "after avg" << std::endl;
delete []best;
std::cout << "after best" << std::endl;
delete []worst;
std::cout << "after worst" << std::endl;
for (int i = 0; i < times; i++) {
std::cout << "after " << i << std::endl;
delete[] resTable[i];
}
delete []resTable;
std::cout << "last flag" << std::endl;
return 0;
}
In the main function I have a dynamically created array and store all data in it but it gives a segmentation fault when it reaches in last row to store data.
So I tried to skip storing in last row and it worked but this time when deleting at the end it again gives me the error "munmap_chunk() : invalid pointer"
I have checked other questions related to this but couldn't find what I am doing wrong here.
I know we can do it better with vectors but I am just trying to get a better understanding of the inner workings of pointers and memory allocation.
You've got two instances of reading/writing outside of allocated memory bounds, and two instances of using an uninitialized pointer.
First, in insersionSort:
while (key < array[j] && j >= 0) {
You use j to index the array before checking if the value is positive. This results in reading before the start of the array. You want to check j first:
while ( j >= 0 && key < array[j]) {
Then you have this in getRandomArray:
for (int i = 0, j = size; i < size; i++, j--) {
You start j at size, then use it to index the array. This writes past the end of the array. You want to start one element earlier:
for (int i = 0, j = size - 1; i < size; i++, j--) {
Finally, there's getComplx:
double getComplx(int* arry, int size) {
struct timeval *start, *end;
std::cout << "comp flag " << std::endl;
gettimeofday(start, NULL);
insertionSort(arry, size);
gettimeofday(end, NULL);
double timeTaken = (end->tv_sec - start->tv_sec) * 1000000 + (end->tv_usec - start->tv_usec);
return timeTaken;
}
The gettimeofday function expects a pointer to a struct timeval, but in both cases you pass it an uninitialized pointer. Rather than making start and end pointers, make them instances of struct timeval and pass their addresses:
double getComplx(int* arry, int size) {
struct timeval start, end;
std::cout << "comp flag " << std::endl;
gettimeofday(&start, NULL);
insertionSort(arry, size);
gettimeofday(&end, NULL);
// also change -> to .
double timeTaken = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_usec - start.tv_usec);
return timeTaken;
}

Write a function that returns a pointer to the maximum value using pointers c++

This is the problem that I'm trying to solve for class in C++.
Write a function that returns a pointer to the maximum value of an array of floating-point data: double* maximum(double* a, int size). If size is 0, return nullptr.
The issues I'm having are that:
The final output is not the correct location for the maximum value in the array.
An error that says: "cannot convert 'double**' to 'double*' in the initialization".
If I use nullptr at any point in this code, CodeBlocks gives me an error.
#include <iostream>
using namespace std;
// return pointer to location from function
double * maximum(double* a, int size)
{
double maxVal = a[0]; // this is the starting max value
double* max_pos = &a; // points to the value in a[0]
// initialis]ze both variables
for(int i = 0; i < size; i++){
if(a[i] > maxVal){
maxVal = a[i];
cout << max_pos << endl;
max_pos = &a[i];
}
}
// return address
return max_pos;
}
int main()
{
double myarr[5];
int i = 0;
int arrSize = 5;
cout << "Input 5 floating point values for your array" << endl;
for(i = 0; i < arrSize; i++){ // loop to input values
cin >> myarr[i];
}
for(int j = 0; j < arrSize; j++){
cout << "Location for " << myarr[j] << " = " << &myarr[j] << endl;
}
double* maxNum = maximum( myarr, arrSize);
cout << &maxNum << endl;
return 0;
}
This is the output I'm getting after finding max_pos:
The code you showed has a few mistakes in it:
using namespace std; is bad!
you are not following your instructions to return nullptr when size is 0.
you are trying to initialize max_pos (a double*) with &a (a double**), which is a compiler error.
you are passing &maxNum (a double**) to std::cout, printing the address of the maxNum variable itself, not the address that it is pointing to (the found array element). You need to pass maxNum (a double*) if you want to print the address of the found element, or pass *maxNum (a double) if you want to print the value of the found element.
Try something more like this instead:
#include <iostream>
// return pointer to location from function
double* maximum(double *a, int size)
{
if (size == 0) return 0;
// initialize both variables
double* max_pos = a; // points to the value in a[0]
double maxVal = *max_pos; // this is the starting max value
std::cout << "max_pos = " << max_pos << " (" << maxVal << ")" << std::endl;
for(int i = 1; i < size; ++i){
if (a[i] > maxVal){
max_pos = &a[i];
maxVal = *max_pos;
std::cout << "max_pos = " << max_pos << " (" << maxVal << ")" << std::endl;
}
}
// return address
return max_pos;
}
int main()
{
const int arrSize = 5;
double myarr[arrSize];
std::cout << "Input " << arrSize << " floating point values for your array" << std::endl;
for(int i = 0; i < arrSize; ++i) { // loop to input values
std::cin >> myarr[i];
}
for(int j = 0; j < arrSize; ++j) {
std::cout << "Location for " << myarr[j] << " = " << &myarr[j] << std::endl;
}
double* maxNum = maximum(myarr, arrSize);
std::cout << "maxNum = " << maxNum << " (" << *maxNum << ")" << std::endl;
return 0;
}
Live Demo
And then, you can throw it all away and use STL algorithms instead, like std::max_element():
#include <iostream>
#include <algorithm>
#include <iterator>
int main()
{
const int arrSize = 5;
double myarr[arrSize];
std::cout << "Input " << arrSize << " floating point values for your array" << std::endl;
// loop to input values
std::copy_n(std::istream_iterator<double>(std::cin), arrSize, myarr);
for(int i = 0; i < arrSize; ++i) {
std::cout << "Location for " << myarr[i] << " = " << &myarr[i] << std::endl;
}
double *maxNum = std::max_element(myarr, myarr + arrSize);
std::cout << "maxNum = " << maxNum << " (" << *maxNum << ")" << std::endl;
return 0;
}
Live Demo

Set array dimension at runtime

I have a struct, which, depending on user inputs at runtime, will either require a 1D array or a 3D array. It will never need both. Right now, I have it set up like in the sample code below, with separate variables that can point to either a 1D array, or a 3D array. I would like to have just one variable in the struct that can point to either a 1D array or a 3D array, where the dimension is set at runtime. I have intermediate knowledge of C, and am a beginner with C++. I'd be willing to accept an answer based on C++ concepts but only if there is no slowdown (or negligible slowdown) compared to using C when iterating over the values. If it's a 3D array, then the for loops that access and change the array's values are the biggest bottleneck in my code. Once the array is set up, I won't need to change the dimension or size of the array.
Is there a way to do this, or should I just settle for always having an extraneous variable in my struct?
#include <iostream>
using namespace std;
typedef struct {
int dim;
int *one_d_arr;
int ***three_d_arr;
} Struct;
int main() {
int count = 0;
int *arr1 = (int*) malloc(2 * sizeof(int));
arr1[0] = 0;
arr1[1] = 1;
int ***arr3 = (int***) malloc(2 * sizeof(int**));
for (int i=0; i<2; i++) {
arr3[i] = (int**) malloc(2 * sizeof(int*));
for (int j=0; j<2; j++) {
arr3[i][j] = (int*) malloc(2 * sizeof(int));
for (int k=0; k<2; k++) {
arr3[i][j][k] = count++;
}
}
}
Struct s;
s.one_d_arr = NULL;
s.three_d_arr = NULL;
cout << "Enter number of dimensions: ";
cin >> s.dim;
if (s.dim==1) {
s.one_d_arr = arr1;
cout << s.one_d_arr[0] << ", " << s.one_d_arr[1] << endl;
}
else if (s.dim==3) {
s.three_d_arr = arr3;
cout << s.three_d_arr[0][0][0] << ", " << s.three_d_arr[0][0][1] << endl;
cout << s.three_d_arr[0][1][0] << ", " << s.three_d_arr[0][1][1] << endl;
cout << s.three_d_arr[1][0][0] << ", " << s.three_d_arr[1][0][1] << endl;
cout << s.three_d_arr[1][1][0] << ", " << s.three_d_arr[1][1][1] << endl;
}
else {
cout << "Must enter 1 or 3" << endl;
}
}
My recommendation is to use two different types here, instead of a single struct. Using an abstract base class, you can make both subclasses conform to a single interface, but they would have different underlying behavior. A very basic example:
class ArrayBase {
int dim;
public:
// This function is pure virtual, which means it's impossible to
// instantiate an instance of ArrayBase. Any class that inherits from
// ArrayBase must implement printArray().
virtual void printArray() = 0;
}
class Array1D : public ArrayBase {
int* array;
void printArray() {
// some code to print this one-dimensional array
}
}
class Array3D : public ArrayBase {
int*** array;
void printArray() {
// some code to print this three-dimensional array
}
}
Later, when you need to use the array, you can dynamically allocate the type you need, like this:
ArrayBase* inputArray;
// if the user wants a 1D array
inputArray = new Array1D();
// if the user wants a 3D array
inputArray = new Array3D();
// this will call the appropriate function to print the array
inputArray->printArray();
If you really want to have a single type, using boost::any is one way to condense your two array pointers into one. I would not recommend this approach, but it would work.
One of the juicy things about the C/C++ pointers is the existence of void pointers. A void pointer can point to anything you want, from int to int ***.
So you can simply use the following code:
#define CAST1(arr) ((int *)arr)
#define CAST3(arr) ((int ***)arr)
#define CAST(arr,i) CAST##i(arr)
typedef struct {
int dim;
void *arr;
} Struct;
int main()
{
Struct s;
cin >> s.dim;
int count = 0;
if (s.dim == 1){
s.arr = malloc(2 * sizeof(int));
CAST(s.arr, 1)[0] = 0;
CAST(s.arr, 1)[1] = 1;
}
else if (s.dim == 3){
s.arr = malloc(2 * sizeof(int ***));
for (int i = 0; i < 2; i++){
CAST(s.arr, 3)[i] = (int **) malloc(2 * sizeof(int **));
for (int j = 0; j < 2; j++){
CAST(s.arr, 3)[i][j] = (int *)malloc(2 * sizeof(int *));
for (int k = 0; k < 2; k++){
CAST(s.arr, 3)[i][j][k] = count++;
}
}
}
}
if (s.dim == 1) {
cout << CAST(s.arr, 1)[0] << ", " << CAST(s.arr, 1)[1] << endl;
}
else if (s.dim == 3) {
cout << CAST(s.arr, 3)[0][0][0] << ", " << CAST(s.arr, 3)[0][0][1] << endl;
cout << CAST(s.arr, 3)[0][1][0] << ", " << CAST(s.arr, 3)[0][1][1] << endl;
cout << CAST(s.arr, 3)[1][0][0] << ", " << CAST(s.arr, 3)[1][0][1] << endl;
cout << CAST(s.arr, 3)[1][1][0] << ", " << CAST(s.arr, 3)[1][1][1] << endl;
}
else {
cout << "Must enter 1 or 3" << endl;
}
system("pause");
return 0;
}

strncat _emulations_ multiple calls ignore changed n?

For self-study, here there are my 2 version of strncat (one with pointer+offset notation and one array version):
// 08_38.cpp
#include <iostream>
#include <cstring>
char * strncatPtr(char * a, char * b, size_t n);
char * strncatArr(char * a, char * b, size_t n);
int main (void) {
char string1[20] = "foobarqwerty";
char string2[20] = "asd";
// strncat
std::cout << "-----------------------" << std::endl;
std::cout << "--------STRNCAT--------" << std::endl;
std::cout << "-----------------------" << std::endl;
std::cout << strncat(string2, string1, 6) << std::endl;
std::cout << strcpy(string2, "asd") << std::endl;
std::cout << strncatPtr(string2, string1, 4) << std::endl;
std::cout << strcpy(string2, "asd") << std::endl;
std::cout << strncatArr(string2, string1, 3) << std::endl;
std::cout << strcpy(string2, "asd") << std::endl;
return 0;
}
// ------------------------------------
char * strncatPtr(char * a, char * b, size_t n){
unsigned int i = 0;
// go to the end;
for(; *(a+i) != '\0'; i++);
// and start copying
for(unsigned int j = 0;
((*(a+i+j) = *(b+j)) != '\0') && (j < n-1);
j++);
return a;
}
char * strncatArr(char * a, char * b, size_t n){
unsigned int i = 0;
// go to the end;
for(; a[i] != '\0'; i++);
// and start copying
for(unsigned int j = 0;
((a[i+j] = b[j]) != '\0') && (j < n-1);
j++);
return a;
}
I don't get why when i test them it considers size = 6 for every function call
-----------------------
--------STRNCAT--------
-----------------------
asdfoobar
asd
asdfoobar
asd
asdfoobar
asd
but if i test them separately, by commenting 2 different calls each time, they works fine... could you please enlighten me?
If the number of chars copied is less then the length of the string being concatenated then you are not adding a null-terminator to indicate the end of the string.