Storing integers in char* - c++

I am a beginner is c trying something out. How can i pass an integer array to a function expecting char* in c/c++, since the range of char is only -128 to 127 but i want to store numbers from whole range of integers.
Here is what I was trying:
#include<stdlib.h>
#include<stdio.h>
int size = 12;
void print(char* array){
int i,j;
for(i=0;i<size;i++)
for(j=0;j<size;j++)
printf("%d ",*(array+i*size+j));
printf("\n");
}
int main(){
int array[size][size];
int i=0,j=0,k=0;
for(i=0;i<size;i++)
for(j=0;j<size;j++)
array[i][j]=k++;
for(i=0;i<size;i++)
for(j=0;j<size;j++)
printf("%d ",array[i][j]);
printf("\n");
print((char *) array);
return 0;
}
When array is printed inside the main function, the output is correct (numbers 0-143) but inside the print() function, the output is
0 0 0 0 1 0 0 0 2 0 0 0 3 0 0 0 4 0 0 0 5 0 0 0 6 0 0 0 7 0 0 0 8 0 0
0 9 0 0 0 10 0 0 0 11 0 0 0 12 0 0 0 13 0 0 0 14 0 0 0 15 0 0 0 16 0 0
0 17 0 0 0 18 0 0 0 19 0 0 0 20 0 0 0 21 0 0 0 22 0 0 0 23 0 0 0 24 0
0 0 25 0 0 0 26 0 0 0 27 0 0 0 28 0 0 0 29 0 0 0 30 0 0 0 31 0 0 0 32
0 0 0 33 0 0 0 34 0 0 0 35 0 0 0
I don't know what am I doing wrong.
P.S. I need this since I am using apache Zookeeper and the set and get functions it has require arguments of type char* for your data.

The same way you can use any array or pointer when using e.g. send for sockets: You cast the pointer.
Like
int data[DATA_SIZE];
...
send(s, (const char *) data, sizeof(data), 0);
This is very common, as many functions takes pointer to char even for generic data. The big question is what the function does with the data.

C and C++ are different languages.
"Integer array" is not a C type. Please be specific, such as:
int my_array[42];
You don't pass arrays, in C. Unless it is the operand of the sizeof, unary & or _Alignof operators, or is being used as an initializer, an expression with an array type evaluates to the value of a pointer to the first element of the array. Please see "Array Decay" at http://www.iso-9899.info/wiki/Code_snippets
In C, you can always cast a pointer to any complete or incomplete object type to a pointer to char *. int * is a pointer to a complete object type. Knowing these facts, the following code is valid, inside a function body:
int my_array[42];
char * what_i_want;
what_i_want = (char *) my_array;
Then you can pass the 'what_i_want' value to any function accepting a char * argument.
Having said this, you need to understand what the function is expecting. Share the function and some actual code, then perhaps someone will be able to offer greater insight as to how to achieve your goal.

char * can also be used to point to a string, so you can try using the appropriate conversion (int -> string, string -> int) functions to pass these.
If you post code, I can try and provide a more detailed answer.

Char* - it's the only type of pointer, but you can provide this function everything you want.
You can do something like that:
void func(char* aPointer)
{
int* arr = (int*)aPointer;
int firstInt = *arr;
...
}
Of course, this is very brutal way, so in this case you should be very careful, do some checks and so on.

void func(char* c)
{
...
}
int x[5] = {1,2,3,4,5};
func((char*)x);

Related

The size of structure (sizeof) in C++ doesn't correspond the real size in case of arrays

I use dynamic arrays of the following structure:
struct TestStructure
{
unsigned int serial;
int channel;
int pedestal;
int noise;
int test;
};
The sizeof(TestStructure) returns 20, so I assume that there is no padding/alignment in the structure. It's logically because there are only 4-bytes types.
But I discovered that size of structure multiplied by element count is not equal the size of the array. There is an additional pad between elements of the array! So, in the following code:
TestStructure* test_struct = new TestStructure[element_count];
for (int i = 0; i < element_count; i++)
FillStructure(test_struct, i, i, i, i, i, i); // assigning 'i' for all elements
Long_t size_value = element_count * sizeof(TestStructure);
unsigned char* p_value = new unsigned char[size_value];
memcpy(p_value, test_struct, size_value);
The output array of chars contains the additional pads between elements:
sizeof(TestStructure) = 20. element_count = 10. size_value = 200. char array in the hex format:
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
6c 6c 2f 6c
1 0 0 0
1 0 0 0
1 0 0 0
1 0 0 0
1 0 0 0
6f 70 74 2f
2 0 0 0
...
Please, explain me.
Does dynamic array add pads between elements or
Does 'sizeof' operator show wrong size of the structure?
P.S. I use GCC 5.4.0 (Ubuntu 5.4.0-6ubuntu1~16.04.2).
EDIT: I use this code in a macro with ROOT CINT interpreter with GCC compiled library. Sorrry, It seems this bug concerned not with GCC but with ROOT CINT.
EDIT2: Yes, in my ROOT macro (executed by CINT interpreter) sizeof(TestStructure) returns 24 and after that when I call a function of the GCC compiled library (containing the code fragment listed above), the sizeof(TestStructure) returns 20 in the compiled function.
Although a compiler can add packing to the end of a struct, a compiler absolutely cannot add additional packing between the elements when manufacturing an array.
For an array TestStructure[n], the address of the i(th) element must be TestStructure + i * sizeof TestStructure. If this were not true then pointer arithmetic would break horribly.

garbage value in while printing array

I am declaring the array dynamically using new. The array is formed of string length, which I am giving from the user. When I am providing a string of length between 7-11 the array is printing garbage value. Why is it happening?
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<climits>
#include<vector>
#include<ctime>
#include<map>
using namespace std;
int main(){
string str;
cin>>str;
int i,j;
int** arr = new int*[str.length()];
for(i = 0; i < str.length(); ++i)
arr[i] = new int[str.length()];
for(i=0;i<str.length();i++){
for(j=0;j<str.length();j++){
cout<<arr[i][j]<<" ";
}
cout<<endl;
}
return 0;
}
The output for string "BBABCBCAB" is:
36397056 0 8 0 -1 0 1111573058 1094926915 0
0 0 4 0 -1 0 1111573058 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
Why is it happening ? And not for other any string with more than length 12?
You're default-initializing all your ints, which doesn't actually assign them a value. Reading from an indeterminate value is undefined behavior - sometimes you get 0s, sometimes you get some weird values. Undefined behavior is undefined.
If you want all 0s, you need to value-initialize the array:
arr[i] = new int[str.length()]();
// ^^
Or use something like memset or std::fill or std::fill_n.

Strange numbers when array is not initialized in C++ [duplicate]

This question already has answers here:
What happens to a declared, uninitialized variable in C? Does it have a value?
(9 answers)
Closed 7 years ago.
EDIT: ^^^ "duplicate" doesn't mention arrays at all
EDIT2: Hold on that's in C, not C++, isn't there a difference between 2 languages ?!
This question has been bugging me for some time lately. Google search revealed nothing.
So I have this snippet of example C++ code:
int factors[100]; /* note this is not initialized */
int number = /* less than 100 */ 10;
for (int i = 0; i < number; i ++) {
factors[i] = 1;
}
for (int i = 0; i < 100; i ++) {
std::cout << factors[i] << std::endl;
}
The output is (scroll down to bottom)
1
1
1
1
1
1
1
1
1
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1640775680
32767
114023525
624860211
174064279
236792104
-1027703263
587262357
1599638600
32767
17
0
1
0
6778984
1
1640935824
32767
1599638352
32767
1640780406
32767
1599638384
32767
1599638384
32767
1
0
1599638408
32767
6778880
1
1640776264
32767
1599638424
32767
0
0
0
0
0
0
0
0
0
0
Why isn't it either ten 1s or ten 1s and ninety 0s, and why are there so many seemingly random (maybe related to powers of 2?) numbers? I think it may have something to do with memory allocation or something but I'm just a beginner and I've not gotten into this stuff yet.
If you have the declaration
int factors[100]; /* note this is not initialized */
there are two situations:
When declared as a global (file scope) variable, the entire array will be initialised to zeros before your program starts.
When declared as a local (function scope) variable, the array is not initialised and will contain unpredictable numbers.
The uninitialized arrays are filled with garbage values.Garbage values are those values present in that specific memory location before the user requests for it.The memory location have always existed.In many cases the output is 0 as compiler explicitly writes defualt values before returning these locations.But this behaviour is not always exhibited by C/C++ compilers,hence the presence of a varied output.
Thats just the thing, if you don't initialize your arrays, C++ does not guarantee it will be blank

boost serialization hexadecimal decimal encoding of data

I am new to boost serialization but this seems very strange to me.
I have a very simple class with two members
int number // always = 123
char buffer[?] // buffer with ? size
so sometimes I set the size to buffer[31] then I serialize the class
22 serialization::archive 8 0 0 1 1 0 0 0 0 123 0 0 31 0 0 0 65 65
we can see the 123 and the 31 so no issue here both are in decimal format.
now I change buffer to buffer[1024] so I expected to see
22 serialization::archive 8 0 0 1 1 0 0 0 0 123 0 0 1024 0 0 0 65 65 ---
this is the actual outcome
22 serialization::archive 8 0 0 1 1 0 0 0 0 123 0 0 0 4 0 0 65 65 65
boost has switched to hex for the buffer size only?
notice the other value is still decimal.
So what happens if I switch number from 123 to 1024 ?
I would imagine 040 ?
22 serialization::archive 8 0 0 1 1 0 0 0 0 1024 0 0 0 4 0 0 65 65
If this is by design, why does the 31 not get converted to 1F ? its not consistent.
This causes problems in our load function for the split_free, we were doing this
unsigned int size;
ar >> size;
but as you might guess, when this is 040, it truncs to zero :(
what is the recommended solution to this?
I was using boost 1.45.0 but I tested this on boost 1_56.0 and it is the same.
EDIT: sample of the serialization function
template<class Archive>
void save(Archive& ar, const MYCLASS& buffer, unsigned int /*version*/) {
ar << boost::serialization::make_array(reinterpret_cast<const unsigned char*>(buffer.begin()), buffer.length());
}
MYCLASS is just a wrapper on a char* with the first element an unsigned int
to keep the length approximating a UNICODE_STRING
http://msdn.microsoft.com/en-gb/library/windows/desktop/aa380518(v=vs.85).aspx
The code is the same if the length is 1024 or 31 so I would not have expected this to be a problem.
I don't think Boost "switched to hex". I honestly don't have any experience with this, but it looks like boost is serializing as an array of bytes, which can only hold numbers from 0 through 255. 1024 would be a byte with a value 4 followed by a byte with the value 0.
"why does the 31 not get converted to 1F ? its not consistent" - your assumptions are creating false inconsistencies. Stop assuming you can read the serialization archive format when actually you're just guessing.
If you want to know, trace the code. If not, just use the archive format.
If you want "human accessible form", consider the xml_oarchive.

Loading Data from File to Data Structure in C++ and Interpreting It

Okay so this code is killing me.
My goal is to read data from a file where the data is separated by commas, then load that data into an array of structures that is supposed to be a list of "theater seats". The theater seats have certain characteristics, such as "location", "price", and "status". Price is self-explanatory. Location deals with the row and seat number of the "Seat". And status pertains to whether or not it's sold. After that, I have to interpret the data that I pulled from the data file to make a display THAT CAN be easily manipulated by the user if they input a certain choice. But that's not what I'm getting at in this question.
My question is, what would be the best method to load my data structures from the data file?
Let me show you a bit of the data file that I'm reading from.
1, 1, 50, 0
1, 2, 50, 0
1, 3, 50, 0
1, 4, 50, 0
To explain the data file, the first number is the "row", second number is the seat number in that row, the third number is the price, and the final number ("0") stands for the seat being unsold. Had the seat been purchased, the final number would be 1.
Now, here's my code.
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <cstdlib>
#include <cstdio>
#include <conio.h>
using namespace std;
enum seatDimensions{ROWS = 10, SEATS_PER = 16};
//Structures
struct Location
{
int row;
int seatNumber;
};
struct Seat
{
Location seat_location[160];
double ticketPrice;
int status;
int patronID;
};
//GLOBALS
const int MAX = 16;
int main()
{
//arrays for our data
Seat seatList[160];
//INDEX
int index = 1;
//filestream
fstream dataIn;
dataIn.open("huntington_data.dat",ios::in);
if(dataIn.fail()) //same as if(dataIn.fail())
{
cout << "Unable to access the data file." << endl;
return 999;
}
string temp;
getline(dataIn,temp,',');
seatList[index].seat_location[index].row = atoi(temp.c_str());
getline(dataIn,temp,',');
seatList[index].seat_location[index].seatNumber = atoi(temp.c_str());
getline(dataIn,temp,',');
seatList[index].ticketPrice = atof(temp.c_str());
getline(dataIn,temp,'\n');
seatList[index].status = atoi(temp.c_str());
while(!dataIn.eof() && index < MAX)
{
index++;
getline(dataIn,temp,',');
seatList[index].seat_location[index].row = atoi(temp.c_str());
getline(dataIn,temp,',');
seatList[index].seat_location[index].seatNumber = atoi(temp.c_str());
getline(dataIn,temp,',');
seatList[index].ticketPrice = atof(temp.c_str());
getline(dataIn,temp,'\n');
seatList[index].status = atoi(temp.c_str());
}
getch ();
return 0;
}
Now from here, I have to display whether or not the seats are TAKEN or not.
The display should look like this, since none of the seats are taken yet.
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 // 16 across
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
// 10 deep
I know I'm not inputting my data in correctly, because I cannot seem to get this display no matter how I try to cout it. If you can tell where I'm going wrong, please tell me. Any suggestions would be amazing.
Also, if you have any questions for me, just ask. I tried to be as specific as possible considering the question, but I know that it's still pretty vague.
Please help.
EDIT: Thanks to those who answered my question. I ended up going a very different route with my data structure, but pulled a lot from the answers.
You have the problem that each seat has a position in an array and then has an array of positions:
You need:
Location seat_location[160];
changed to:
int seat_row;
int seal_num;
then:
seatList[index].seat_location[index].row = atoi(temp.c_str());
becomes:
seatList[index].seat_row = index / COLS ;
seatList[index].seat_num = index % COLS ;
You may also like to consider actually arranging your data into a 2D array of the same dimensions as your seating.
BTW From my C background I would suggest reading the whole line and using sscanf, e.g.:
char temp[255]; // Use an appropriate maximum line length +3 for \r\n\0
fgets(dataIn, &temp);
sscanf(temp, "%d, %d, %d, %d", &.....
You could also consider implementing this with a regular expression.
Write a function that gets string of input and splits it into items:
std::vector<std::string> splitLine( const std::string &str );
Implement and debug it with string like "1, 1, 50, 0", make sure it returns vector of string with each number as separate element. Then read input line by line, split and convert each string to number separately. You will simplify the code and it will be much easier to make it work.
is it an assignment?
i guess the way you are organizing your data in structure needs to be changed.
Take a structure maybe like this
struct Seat{
double ticketPrice;
int status;
int patronId;
}
and have a two dimensional array like this
Seat seatList[10][16];
first dimension is (row number-1), second dimension is (seat number-1)
and read your data from file like this
string temp;
getline(dataIn,temp,',');
int row = atoi(temp.c_str());
getline(dataIn,temp,',');
int seatNumber = atoi(temp.c_str());
getline(dataIn,temp,',');
//check row and seatnumber > 0
seatList[row-1][seatNumber-1].ticketPrice = atof(temp.c_str());
getline(dataIn,temp,'\n');
seatList[row-1][seatNumber-1].status = atoi(temp.c_str());
Use two simple for loops to print your output from these structures.