Why don't my simple code work in C++? - c++

Error in function realloc(): invalid pointer
int indZero = 0;
int *perZero=NULL;
int zero = 0;//Initialization
ProcessBit(zero,&indZero,&perZero);// Call function
void ProcessBit(int num,int *ind,int **mas)
{
mas=(int**)realloc(&mas,((*ind))*sizeof(int));// Error
mas[num-1]++;//it's correct line
}

A few problems:
The first argument to realloc is the original pointer (or NULL).
Your ProcessBit doesn't really emulate pass-by-reference correctly.
You can use a negative index.
mas is a pointer to a pointer to int, but you use it as a pointer to int.
A "fixed" version might look something like this:
void ProcessBit(int num, int *ind, int **mas)
{
int *temp = realloc(*mas, (*ind + 1) * sizeof(int));
if (temp == NULL)
{
// TODO: Handle error
// TODO: return or exit(EXIT_FAILURE)
}
*mas = temp;
(*mas)[*ind] = 0; // Initial initialization
if (num > 0)
{
(*mas)[num - 1]++;
}
++*ind; // Increase the size
}
Now, if this really was C++ (as you tagged your question) then you should be using std::vector instead, which would solve almost all your problems with much simpler code.

The parameters are wrong. Since you are trying to realloc a NULL pointer it should behave like malloc; however, the header declared in cstdlib is
void* realloc( void* ptr, std::size_t new_size );
The formal parameter mas is already the address of the pointer, so the call should be
*mas=(int*)realloc(*mas,((*ind))*sizeof(int));
(*mas)[num-1]++;
Since realloc handles and returns pointers by copy, not by reference.
You are passing the address of the memory location where the address of a memory location (NULL) is stored to your ProcessBit function, and then the address of that location to the realloc function. The function tries to reallocate memory where the variable mac is stored, on the stack. No wonder it's an invalid pointer.
By passing &mac you are simply taking a step in the wrong direction while dereferencing pointers.

Related

Error reading vector elements via a pointer which has the base address of the vector

My exe is accessing the vector assigned by dll. I am getting the base address via vector.data(). The problem is that the vector probably has more memory space allocated than required. So how do I read the memory that has the actual data allocated.
.dll code
Utf8String ICSClient::SampleMethod2(Utf8String* &p)
{
vector<Utf8String> *temp = new vector<Utf8String>;
temp->push_back("Liu");
temp->push_back("Roy");
temp->push_back("Shanu");
p = temp->data(); // returns the pointer to the underlying array
return success;
}
.exe code
// -----p is a pointer that is allocated the base address of the vector
while (p != NULL)
{
cout << *p << endl;
p++;
}
it appears that the p is not equal to null and then the exception is thrown when reading the memory that is not null.
p won't get equal to NULL by itself. Can't tell exactly, because provided code lacks p pointer definition and ICSClient::SampleMethod2 call, but here you're reading array and then you go out of bounds of the array, which is Undefined Behaviour.
There is a memory leak as well, since you never free the memory allocated for vector and you lose the pointer to it with the end of function.
I see that you return some code here, which is probably a requirement, so you can't return vector. I'd suggest passing std::vector by reference, so you can use it in your function
Utf8String ICSClient::SampleMethod2(std::vector<Utf8String>& data)
{
data.clear();
data.push_back("Liu");
data.push_back("Roy");
data.push_back("Shanu");
return success;
}
EDIT: If passing std::vector by reference is not viable option, then you (and users of your dll) will have to deal with raw C arrays. Unfortunately, when passing array to a function, it gets downgraded to a pointer type, so passing size together with array is a necessity.
Utf8String ICSClient::SampleMethod2(Utf8String** data, size_t* size)
{
*size = 3;
*data = new Utf8String[3];
data[0] = "Liu";
data[1] = "Roy";
data[2] = "Shanu";
return success;
}
Mind you, the user will have to manage memory (delete the array) by himself, which is not really an expected behaviour.

NULL as a parameter

I am a bit confused when you pass NULL as a parameter
for example
int* array_create( int* array,size)
{
array = new int[size];
return array;
}
int main()
{
int* array = array_create(NULL,10);//can we pass NULL in this case?
delete[] array;
return 0;
}
I know the example is kinda stupid, but I am wondering if we can pass NULL as the parameter when the function assigns some heap memory to a pointer and returns it?
When you call your function like this...
int* array = array_create(NULL,10);//can we pass NULL in this case?
...you are getting behaviour like:
int* array_create(...)
{
int* array = NULL;
size_t size = 10; // using size_t as you'd missed any type
array = new int[size];
return array;
}
Ultimately, array is initialised to NULL then shortly afterwards overwritten with the value returned by new, so the initialisation serves no purpose.
For this code, there was simply no point passing an array argument... you could have created a local variable directly:
int* array_create(size_t n)
{
int* array = new int[size];
return array;
}
...or even...
int* array_create(size_t n)
{
return new int[size];
}
I am wondering if we can pass NULL as the parameter when the function assigns some heap memory to a pointer and returns it?
This requirement doesn't make much sense, as the two things are unrelated. You can pass whatever you like, and return whatever you like.
More commonly, a function might do something like:
void dump_bytes(std::ostream& os, unsigned char* p, size_t n)
{
if (p)
for (size_t i = 0; i < n; ++i)
os << static_cast<int>(p[i]) << ' ';
}
In dump_bytes, specifying a p value of NULL would fail the if (p) condition, ensuring the function didn't invoke undefined behaviour by dereferencing via a NULL pointer, even if n was not 0.
Just summarizing from the comments:
Yes, it is completely valid, but in Your example it is completely useless (you know that)
Some examples of this in real code:
In OpenGL you can tell the API if the data you want is coming from is from a buffer:
glBufferData(..., nullptr);
But wait! That's not null, that's nullptr?
Well in a c++11 compiler nullptr is a better option. Because NULL often usually resolves to 0, a version of the method that takes an int instead of a pointer the compiler will choose the int.
Here's some more data on that:
http://en.cppreference.com/w/cpp/language/nullptr
Also, if you want to edit an array, you should pass a pointer to a pointer.

What's the bug with a possible wrapper function of realloc C function?

I like to know the possible bug in the following possible wrapper function of the realloc C function:
void reallocX(void** ptr, size_t size)
{
void *new_ptr = realloc(*ptr, size);
if (new_ptr != NULL)
{
if (new_ptr != *ptr)
{
*ptr = new_ptr;
}
}
else
{
printf( "Help! realloc returned NULL!\n");
exit( EXIT_FAILURE);
}
}
.
I know that it is based in the possible wrapper function of the malloc C function, that is:
void *
mallocX (size_t nbytes)
{
void *ptr;
ptr = malloc (nbytes);
if (ptr == NULL) {
printf( "Help! malloc returned NULL!\n");
exit (EXIT_FAILURE);
}
return ptr;
}
. This malloc C function wrapper function is based on the "mallocc" C function of this webpage.
Thanks for any help.
A null-pointer return value from realloc may indicate either:
That the function did not allocate storage.
That the size parameter was zero and the memory was deallocated.
Your code covers the first possibility, but not the second. A null return value can be valid, indicating that deallocation of a memory block completed succesfully. Signalling an error under these conditions is a bug.
Note this applies for C90 C++98
As noted in the comments, passing a size parameter of 0 is implementation specific in C99/C11 C++11.
There is at least one bug; this line:
if (new_ptr != *ptr)
invokes undefined behavior. Any use of the old pointer, especially comparison with the new one, after realloc succeeds, is forbidden. You need to make the assignment unconditionally.
Further, while this is not an internal bug, the external API is misdesigned and error-prone. Often the type of the caller's pointer will not be void * but some other pointer type like char * or struct foo *, and you'll have users doing:
reallocX((void **)&myptr, size);
This causes your function to invoke undefined behavior via aliasing violations (at the very least; possibly also out-of-bound writes if different pointer types vary in size/representation) because it's accessing a void * object at an address that does not point to a void * object but to some other type of pointer object.
These kinds of wrappers are simply harmful and need to be rejected. There's no way to do them right/safely.

Pass char pointer/array to a function

I am trying to understand char pointer in C more but one thing gets me.
Supposed I would like to pass a char pointer into a function and change the value that pointer represents. A example as followed:
int Foo (char *(&Msg1), char* Msg2, char* Msg3){
char *MsgT = (char*)malloc(sizeof(char)*60);
strcpy(MsgT,"Foo - TEST");
Msg1 = MsgT; // Copy address to pointer
strcpy(Msg2,MsgT); // Copy string to char array
strcpy(Msg3,MsgT); // Copy string to char pointer
return 0;
}
int main() {
char* Msg1; // Initial char pointer
char Msg2[10]; // Initial char array
char* Msg3 = (char*)malloc(sizeof(char) * 10); // Preallocate pointer memory
Foo(Msg1, Msg2, Msg3);
printf("Msg1: %s\n",Msg1); // Method 1
printf("Msg2: %s\n",Msg2); // Method 2
printf("Msg3: %s\n",Msg3); // Method 3
free(Msg1);
free(Msg3);
return 0;
}
In the above example, I listed all working methods I know for passing char pointer to function. The one I don't understand is Method 1.
What is the meaning of char *(&Msg1) for the first argument that is passed to the function Foo?
Also, it seems like method 2 and method3 are widely introduced by books and tutorials, and some of them even referring those methods as the most correct ways to pass arrays/pointers. I wonder that Method 1 looks very nice to me, especially when I write my API, users can easily pass a null pointer into function without preallocate memory. The only downside may be potential memory leak if users forget to free the memory block (same as method 3). Is there any reason we should prefer using Method 2 or 3 instead Method 3?
int f(char* p) is the usual way in C to pass the pointer p to the function f when p already points to the memory location that you need (usually because there is a character array already allocated there as in your Method 2 or Method 3).
int f(char** p) is the usual way in C to pass the pointer p to the function f when you want f to be able to modify the pointer p for the caller of this function. Your Method 1 is an example of this; you want f to allocate new memory and use p to tell the caller where that memory is.
int f(char*& p) is C++, not C. Since this compiles for you, we know you are using a C++ compiler.
Consider what happens when you take an argument of type int& (reference to int) :
void f(int &x) {
x++;
}
void g(int x) {
x++;
}
int main() {
int i = 5;
f(i);
assert(i == 6);
g(i);
assert(i == 6);
}
The same behaviour can be achieved by taking a pointer-to-int (int *x), and modifying it through (*x)++. The only difference in doing this is that the caller has to call f(&i), and that the caller can pass an invalid pointer to f. Thus, references are generally safer and should be preferred whenever possible.
Taking an argument of type char* (pointer-to-char) means that both the caller and the function see the same block of memory "through" that pointer. If the function modifies the memory pointed to by the char*, it will persist to the caller:
void f(char* p) {
(*p) = 'p';
p = NULL; //no efect outside the function
}
int main() {
char *s = new char[4];
strcpy(s, "die");
char *address = s; //the address which s points to
f(s);
assert(strcmp(s, "pie") == 0);
assert(s == address); //the 'value' of the variable s, meaning the actual addres that is pointed to by it, has not changed
}
Taking an argument of type char*& ( reference-to-(pointer-to-char) ) is much the same as taking int&:
If the function modifies the memory pointed to by the pointer, the caller will see it as usual. However, if the function modifies the value of the pointer (its address), the caller will also see it.
void f(char* &p) {
(*p) = 'p';
p = NULL;
}
int main() {
char *s = new char[4];
strcpy(s, "die");
char *address = s; //the address which s points to
f(s);
assert(strcmp(address, "pie") == 0); //the block that s initially pointed to was modified
assert(s == NULL); //the 'value' of the variable s, meaning the actual addres that is pointed to by it, was changed to NULL by the function
}
Again, you could take a char** (pointer-to-pointer-to-char), and modify f to use **p = 'p'; *p = NULL, and the caller would have to call f(&s), with the same implications.
Note that you cannot pass arrays by reference, i.e. if s was defined as char s[4], the call f(s) in the second example would generate a compiler error.
Also note that this only works in C++, because C has no references, only pointers.
You would usually take char** or char*& when your function needs to return a pointer to a memory block it allocated. You see char** more often, because this practice is less common in C++ than in C, where references do not exist.
As for whether to use references or pointers, it is a highly-debated topic, as you will notice if you search google for "c++ pointer vs reference arguments".

Why would a change in a function header cause a Pointer assignment to not function?

When I change the last parameter in the function header from char Findthis[64] to char * Findthis when debugging the Testthis=&*Look_in; assignment breaks. Look_in has a memory address and member values but Testthis is not being assigned that pointer location. Why is this happening?
struct Node * ProbableMatch(struct Node * Look_in, int MaxNodes,
char Findthis[64])
{
char Findit[64];
strcpy_s(Findit,64,Findthis);
struct Node * CurrentHighProb;
CurrentHighProb=new(Node);
struct Node * Testthis;
Testthis=new(Node);
Testthis=&*Look_in;
while((Testthis) || (i!=(ccounter-1)))
{ //This Testthis does not cause exception
string str1;
string str2;
n1=sizeof(Testthis->NAME);
n2=sizeof(Findit);
n=0;
while((Testthis->NAME[n]!='\0') && (n<=n1)){
//While Testthis->NAME here causes the exception
if(Testthis->NAME[n]=='-'){Testthis->NAME[n]=' ';}
n++;
}//end of while
//_DIFFERENT PART OF PROGRAM____
std::string Findme;
cout<<"Enter varible to find. Type quit to quit, case sensative."<<endl;
cin>>Findme;
char * writable = new char[Findme.size()+1];
std::copy(Findme.begin(),Findme.end(),writable);
writable[Findme.size()] = '\0';
if((Findme.compare("quit")!=0) ^ (Findme.compare("Quit")!=0) ^ (Findme.compare("QUIT")!=0)){
ProbableMatch(head,ccounter,writable);
}
delete [] writable;
//_ NODE____
struct Node
{ public:
int VARID,counter,prob;
char NAME[64];
char DESCRIPTION[1024];
struct Node* next;
}node, *pNode=&node;
Looks more like C code. Why are you using C-strings and std strings? In any case, it looks like your error is unrelated. The assignment before Testthis = &*Look_in is useless (not to mention the new call leaks memory). In this case, there is no reason to first dereference your Look_in node and then take the address. You should be able to simply change that statement to Testthis = Look_in.
However, if this is a runtime error, be certain that Look_in != NULL or is not deleted somewhere else.
It looks like you have small confusion on pointers overall; so here is a quick run-down.
Pointers point to a memory location at which some value is stored. So when you declare a pointer and assign it some memory location, you are telling that pointer where in memory to look for some item. When you dereference a valid, non-null pointer, you can get the value which that memory location holds. For instance,
Node x[64]; // An array of 64 nodes
Node * t = x; // t points to element 0 of x. Therefore, changing values of x changes values of t and changing values of t changes values of x
Furthermore, memory allocation/deallocation is a different story. Stack memory (as declared above for both of those declarations) is managed by the operating system. However, heap allocation is up to you (i.e. new/delete).
Node * x = new Node;
// Do stuff with your node - it is on the heap, so it is persistent until you explicitly remove it
delete x;
The biggest difference between the stack and the heap is that heap memory exceeds the life of the function. For example, each function gets its own stack-frame to declare variables on. However, when the function exits, then the stack-frame is freed. Heap memory, however, can hold values which are not exclusive to a single function lifetime.
A simple example is this:
int* giveMeAnInt()
{
int x;
return &x;
}
In the function above, we declare a local variable, and try to return its address as a pointer to that value. However, after we return, that value is popped off the stack anyway since the function has ended. To do this properly you would have to:
int* giveMeAnInt()
{
int* x = new int;
return x;
}
The second example declares a variable on the heap and returns its address. But do not forget, if you use new, you must delete it later. Another quick example (using the working version of the code above i.e. example 2)
...
int * z = giveMeAnInt();
cout<< *z << endl;
delete z; // Free the memory allocated by the giveMeAnInt() function
...
That is a lot of quick information, but good luck.
EDIT
Perhaps if you are crashing at ...->NAME[n], then NAME[n] does not exist. Notice that you are effectively dereferencing Testthis at sizeof(Testthis->NAME) so the problem is not with the pointer. If you are looking for the number of characters in the string for a pointer, then you must use strlen() and not sizeof().
Here is the problem we are facing: the difference between an array and a pointer. If you declare char someArray[64], then sizeof(someArray) == 64. However, if you declare char* someArray, then sizeof(someArray) == 4 (since sizeof(char*) == 4, assuming 32-bit machine. But for now, the constant doesn't matter) and not the actual number of characters. To be safe, you should instead simply use strlen(someArray) which will work as expected for both declarations.
Ok looks like the std::string to char * conversion was causing leaks.
Switched to a vector option as suggested here: How to convert a std::string to const char* or char*?
Problem went away. I'll have to trace the actual memory later but I find it odd that that string memory was placed right next to the begining of the linked-list.