• Advertisement
Sign in to follow this  

read int from char * question

Recommended Posts

inline int read_int_from_stream(int count, int & index, char * src)
{
char * psrc = &src[index];
int dst;
memcpy(&dst, psrc, (size_t)count);
index = index + count;
psrc = 0;

return dst;
}

is this code above correct, i need that to know because this is the one of two functions i use and i need to find out whoch one is causing problems

Share this post


Link to post
Share on other sites
Advertisement

Write a couple of unit tests to check it works. It's some work, but it saves you asking at forums, and getting responses / discussion.

The "psrc = 0" is quite usless at least, as the variable goes out of scope 2 line further.

Share this post


Link to post
Share on other sites

Hard to be certain without context. This appears to be for deserialization? I think it has a happy path that could work as expected.

For example:

int main()
{
   int x = 42;
   char buffer[sizeof(x)];
   memcpy(buffer, &x, sizeof(int));
 
   int index = 0;
   int result = read_int_from_stream(sizeof(int), index, buffer);
   printf("Result: %d\n", result);
}

That said, there are a few things you could change about the code.

A likely issue is if the caller passes a value of "count" that is not equal to "sizeof(int)". If "count" is bigger, then you have undefined behaviour (likely manifesting as overwriting adjacent memory to "dst"). If "count" is smaller, then you have undefined behaviour as some part of "dst" remains uninitialised, likely manifesting as unexpected return values. It would be simpler to remove the parameter and use sizeof(int) rather than accept a parameter that could be potentially incorrect.

Other possible issues include:

     

  • Caller passes a negative "count"

  • Caller passes an invalid "src" buffer pointer (e.g. uninitialised, null)

  • Buffer pointer is valid but points to uninitialised data

  • Buffer data was never generated from the bit pattern of an int

  • Buffer data comes from another system with different endianess or sizeof(int)

  • "index" is or becomes out of range with respect to the buffer length

    Also, it would be nice if "src" were const.

Share this post


Link to post
Share on other sites

it seems ftp client along with http receives some garbage data, that cannot be decoded.\

 

and yes i did the conversion it works.

Edited by WiredCat

Share this post


Link to post
Share on other sites


inline int read_int_from_stream(int count, int & index, char * src)
{
char * psrc = &src[index]; // you use address of a very pointer, why not char * psrc=(src+index*4) ..considerin' if int is 4 chars
int dst;
memcpy(&dst, psrc, (size_t)count);
index = index + count;
psrc = 0;

return dst;
}

Share this post


Link to post
Share on other sites

I am writting in this separate post, that you should stop making code in C++, at least temporarily, to stress it out. For your own wellness and security. Unless this code you posted is for a very educational purpose of your own. Now to your mad code...

Share this post


Link to post
Share on other sites

inline int read_int_from_stream(int count, int & index, char * src)

you use index variable of int type as a parameter to be only red from, yet you pass it as a reference, mind blowing
{
char * psrc = &src[index];

you have a pointer char* src to bytes, but you use address of this pointer, and use index variable reference for indexing !
int dst;
memcpy(&dst, psrc, (size_t)count);

you copy from some random space in memory arbitrary size of bytes into a local variable of int type!
index = index + count;

you add to a memory reference an integer
psrc = 0;

return dst;
}

 

So, you realy need to learn something about memory unmanaged languages and approach them much more carefully.

Share this post


Link to post
Share on other sites

JohnnyCode, not really sure you know what you are talking about.

you use index variable of int type as a parameter to be only red from, yet you pass it as a reference, mind blowing

it is actually NOT read from only as evident by the index = index + count line of the code

 

char * psrc = &src[index]; you have a pointer char* src to bytes, but you use address of this pointer, and use index variable reference for indexing !

This gets a pointer to a specific location within the src buffer.  What is wrong with that?  He could have just did char* psrc = src + index, but either way same thing and I see nothing wrong with it. 

 

int dst; memcpy(&dst, psrc, (size_t)count); you copy from some random space in memory arbitrary size of bytes into a local variable of int type!

He is not copying from "some random space in memory".  It is from the space he specifically calculated as being in the src buffer passed in.  It is somewhat "arbitrary" the number of bytes as it is a passed in parameter.  That would be better to use sizeof(int) if he is indeed reading it into an int.  And yes he is reading it into a local variable....but he is returning that value at the end.  What is wrong with that?

 

index = index + count; you add to a memory reference an integer

index is an int.  count is an int.  how is that a memory reference adding to an integer?  he is using index to guess what, index in his array!!!  How else would you index other locations in an array or buffer without adding to the index?

 

So, you realy need to learn something about memory unmanaged languages and approach them much more carefully.

pot. kettle. black. 

Share this post


Link to post
Share on other sites

JohnnyCode, not really sure you know what you are talking about.

 

 

you use index variable of int type as a parameter to be only red from, yet you pass it as a reference, mind blowing

it is actually NOT read from only as evident by the index = index + count line of the code

 

You are right on this one, but both, count and index, are number values that exist on the parameter scope- out of the function, so it is at least strange for someone to pass an int (the index)- and, without knowing it, earn it altered.

 

char * psrc = &src[index]; you have a pointer char* src to bytes, but you use address of this pointer, and use index variable reference for indexing !

This gets a pointer to a specific location within the src buffer.  What is wrong with that?  He could have just did char* psrc = src + index, but either way same thing and I see nothing wrong with it. 

 

No, it uses address of a 32bit/64bit pointer, then adds index to it, what is an address of some int

 

int dst; memcpy(&dst, psrc, (size_t)count); you copy from some random space in memory arbitrary size of bytes into a local variable of int type!

He is not copying from "some random space in memory".  It is from the space he specifically calculated as being in the src buffer passed in.  It is somewhat "arbitrary" the number of bytes as it is a passed in parameter.  That would be better to use sizeof(int) if he is indeed reading it into an int.  And yes he is reading it into a local variable....but he is returning that value at the end.  What is wrong with that?

 

No, he specificaly calculated a random point in memory literaly, becouse of what I mentioned upper, and if count is a bigger number, code will attempt to put more bytes to int dst variable.

 

index = index + count; you add to a memory reference an integer

index is an int.  count is an int.  how is that a memory reference adding to an integer?  he is using index to guess what, index in his array!!!  How else would you index other locations in an array or buffer without adding to the index?

 

index is a reference, an address to memory where the passed parameter is, count is an int, all integer numbers, thus can be added.

 

So, you realy need to learn something about memory unmanaged languages and approach them much more carefully.

pot. kettle. black. 

 

You should, or deal with uncorrectable memory leaks.

Share this post


Link to post
Share on other sites

It really sounds like you don't understand the difference between references and pointers. Can you, without testing, tell me what the following quick code would output? Be as specific as you are able to.

I know the difference, it sounds you seem to not pick it up from me, I'll try to phrase it in a more definitive way then:

-Reference provides adress of a variable/ a pointer to the memory of the variable.

-Pointer is a whole unsigned integer number, that is an address in memory, can be of 4 or 8 bytes large.

int value=1;

myFirstFunction(value);/*Console is written some whole number that points to the momory where 4 bytes on "value are"*/

myFirstFunction(1); /* Console is written some whole number that points to the memory where 4 bytes of a stacked local param is */

mySecondFunction(&value); /*Console is written some whole number that points to the memory where 4 bytes on "value are"*/

int main()
{
int myInt = 7;

myFirstFunction(myInt); // as I said, address of myInt
mySecondFunction(&myInt);// as I siad, same number
}

Share this post


Link to post
Share on other sites
I know the difference, it sounds you seem to not pick it up from me.

No, you do not know, as demonstrated by your answer:

 

 

int value=1; myFirstFunction(value);/*Console is written some whole number that points to the momory where 4 bytes on "value are"*/ myFirstFunction(1); /* Console is written some whole number that points to the memory where 4 bytes of a stacked local param is */

Blantantly wrong.

int value = 1;
myFirstFunction(value);

Will print out "1". References behave exactly like value/variables wherever they are used. In order to get the address of the thing the reference points to, you have to promote it to a pointer via &. (&value).

myFirstFunction(1);

This won't even compile (on a standard-comformant compiler). You cannot bind a temporary to a non-const reference.

Edited by Juliean

Share this post


Link to post
Share on other sites

 

It really sounds like you don't understand the difference between references and pointers. Can you, without testing, tell me what the following quick code would output? Be as specific as you are able to.

I know the difference, it sounds you seem to not pick it up from me, I'll try to phrase it in a more definitive way then:

-Reference provides adress of a variable/ a pointer to the memory of the variable.

-Pointer is a whole unsigned integer number, that is an address in memory, can be of 4 or 8 bytes large.

int value=1;

myFirstFunction(value);/*Console is written some whole number that points to the momory where 4 bytes on "value are"*/

myFirstFunction(1); /* Console is written some whole number that points to the memory where 4 bytes of a stacked local param is */

mySecondFunction(&value); /*Console is written some whole number that points to the memory where 4 bytes on "value are"*/

int main()
{
int myInt = 7;

myFirstFunction(myInt); // as I said, address of myInt
mySecondFunction(&myInt);// as I siad, same number
}

 

You are wrong.

 

http://cpp.sh/2thd3

Press the "Run" button (lower-right) and see the output. This is the correct and expected behavior.

Share this post


Link to post
Share on other sites

In order to get the address of the thing the reference points to, you have to promote it to a pointer via &. (&value).

In my knowledge, if a parameter is declared as Type &vari , and recieves an instance of Type on itself, it will provide sole address of that variable. Either- it is not actual anymore, or, it hasn't been true about basic integrated types of the language?

I have gonne to the web-page, and for the 98 standard, the one before C++11, compilation hangs on work, if I apply a custom type instead of int type to the inspected variable. Your observation about a need to reference & before the passed variable could not apply to not-value passed instances to parameters, I am still investigating this issue.

 

 

References behave exactly like value/variables wherever they are used. In order to get the address of the thing the reference points to, you have to promote it to a pointer via &. (&value).

Very inccorrect generalization, you must admit that's actualy omitting a reference existance?

Share this post


Link to post
Share on other sites

So this code hang on me for the very link link, I alter only compilation standard to first one.

#include <iostream>

class SomeType{
    public:
    SomeType(){}
    int a;
    int b;
    int c;
    };
    
void myFirstFunction(SomeType &value)
{
    std::cout << value << std::endl;
}

void mySecondFunction(SomeType *value)
{
    std::cout << value << std::endl;
}

int main()
{
  SomeType myInt();
  
  myFirstFunction(myInt);
  mySecondFunction(&myInt);
}

Share this post


Link to post
Share on other sites
Very inccorrect generalization, you must admit that's actualy omitting a reference existance?

What are you talking about?

I said references behave like a value-type, of course they point to another variable, but the point is this - an operation cannot possibly aquire the address of whatever the reference is pointing to, without promoting to pointer.

All of this:

int x = 1;
int& y = x;

y += 1; // does NOT increment the address
std::cout << y;
y = 5; // does NOT set the address to 5
printf("%i", y);

Is functionally 100% equivalent to:

int x = 1;

x += 1;
std::cout << x;
x = 5;
printf("%i", x);

The reference acts as an alias to another variable. Sure its underneath value is a pointer like 0xAB6492F, but whenever you perform another operation on it, it performs the operation on the original variable, as if the reference was a pointer that has been wrapped with "(*pValue)" . If you want to get the address, you need to use &.

EDIT:

 

So this code hang on me for the very link link, I alter only compilation standard to first one.

 

Yeah, this code does not compile. First off:

SomeType myInt();

Does not create an instance of SomeType, but a SomeType (*)() function pointer. Change it to:

SomeType myInt;

Plus:

void myFirstFunction(SomeType &value)
{
    std::cout << value << std::endl; // compilation error
} 

I'm not going to explain why this fails. Take what I explained about references, and you should see for yourself why cout cannot print SomeType&, but can print SomeType*.

Edited by Juliean

Share this post


Link to post
Share on other sites

n my knowledge, if a parameter is declared as Type &vari , and recieves an instance of Type on itself
 

I don't understand what you mean with the bolded part.

 

I have gonne to the web-page, and for the 98 standard, the one before C++11, compilation hangs on work

The output is the same for C++98, C++11 and C++14. This is fundamental stuff, and has not changed.

 

The altered code you posted does not compile. std::cout is not defined for the custom class, and that's not the correct way to create a new instance of the variable type.

Share this post


Link to post
Share on other sites

In my knowledge this'd have been equivalent to that code:

int x = 1;
int& y = x; // snatches addreess of x into actual int* y

*y += 1; // does NOT increment the address
std::cout << *y;
*y = 5; // does NOT set the address to 5
printf("%i", *y);

I havent used references for so long. I am still not sure for pre-11 standard???

Since, for example:

int* a;

int** ap=&a;

**ap - provides *a

Share this post


Link to post
Share on other sites

int x = 1;
int& y = x; // snatches addreess of x into actual int* y
*y += 1; // does NOT increment the address

This does not compile. You do not understand how references work, and you should look them up.
 
 
 

I havent used references for so long. I am still not sure for pre-11 standard???

 
References in C++ have not ever changed, as far as I know(?). You are just mistaken.
Part of the problem is that the & symbol means two different things:

int a = 5;
int &b = a; //Here, the & symbol means "reference".
int a = 5;
int *b = &a; //Here, the & symbol means "address of".

This is actually somewhat similar to the * symbol:

int *a; //Here, the * symbol means "pointer"
int *a = new int;
*a = 5; //Here, the * symbol means "dereference".
Edited by Lactose

Share this post


Link to post
Share on other sites

This does not compile. You do not understand how references work, and you should look them up.

Yes, I know, this is how I expected it to work, and I must admit, that I have used it in that way long ago?

Share this post


Link to post
Share on other sites

and I must admit, that I have used it in that way long ago?

I'm not an expert on changes made to C++, but I'm fairly certain references have never worked like that, and that they have always worked the way we (me + ncsu121978 + Juliean) have described in this thread. 

Share this post


Link to post
Share on other sites

Would agree with Lactose, as far as I can remember I started coding with C++ 98 and am pretty sure that even since that standard it has worked the same way as it works now, I mean cant speak for before then.. but that is going back some 20 years to reach that kinda age :o

Share this post


Link to post
Share on other sites

I know that Visual C++ compiler extensions (in the past and maybe today) would bind temporary variables when passing by reference to non-const functions. This is different from passing a constant by non-const reference though, but maybe early compilers like Visual C++ 6.0 allowed that too for some reason. It wasn't very standard's compliant, after all. Alternately, Johnny Code is remembering wrong.

Edited by nobodynews

Share this post


Link to post
Share on other sites

I know that Visual C++ compiler extensions (in the past and maybe today) would bind temporary variables when passing by reference to non-const functions. This is different from passing a constant by non-const reference though, but maybe early compilers like Visual C++ 6.0 allowed that too for some reason.

I haven't used references for myself. I have worked in Visual C++ 6.0 professionaly, and I didn't encounter references on the scope of entire project code base.

I think references quite break memory security, since you can introduce them to (type*) parameters of functions, while they can be addresses of local/temporary variables, breaking heap allocation guarantees.

WiredCat could have done this

inline int read_int_from_stream(int count, int index, char * src)
{

return *((int*)(src+index*4))

}

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.
Sign in to follow this  

  • Advertisement