Weird error while using realloc [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am running below code and i am getting output as 8 0 4, rather 8 9 4. Can you please help me understand the problem with this code-
#include <cstdlib>
#include <iostream>
using namespace std;
int main() {
int *p;
p = (int*)calloc(2, sizeof(int));
*(p + 0) = 8;
*(p + 1) = 9;
p = (int*)realloc(p, 3);
*(p + 2) = 4;
for (int i = 0; i < 3; i++)
cout << p[i] << " ";
free(p);
p = NULL;
}

The realloc function needs the size on bytes and not elements.
You need to do
int *temp = realloc(p, 3 * sizeof(*temp));
if (temp == NULL)
{
// Handle error...
}
p = temp;
Note that I use a temporary variable for the result of realloc. This is because if realloc fails it will return NULL and reassigning the result back to the pointer you pass as the first argument then you will lose the original pointer.

The size specified as an argument to realloc() must be computed as a number of bytes. As you found out yourself, the simple fix is
p = (int*)realloc(p, 3 * sizeof(int));
Incidentally, you could use the type of *p instead of int to avoid potential inconsistencies if the type of p changes later:
p = (int*)realloc(p, 3 * sizeof(*p));
But since the cast is needed in C++, the inconsistency at least be visible.
You should also test whether calloc() and realloc() succeeded. They do not throw exception but return NULL when out of memory.
Note that you should decide whether you program in C or C++. These languages have a common ancestry but have diverged notably and some idioms used in one are considered bad style in the other, as more appropriate and safer constructs are available.
Here is a corrected version of your program in C:
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *p = calloc(2, sizeof(*p));
assert(p != NULL);
*(p + 0) = 8;
*(p + 1) = 9;
p = realloc(p, 3 * sizeof(*p));
assert(p != NULL);
*(p + 2) = 4;
for (int i = 0; i < 3; i++) {
printf("%d ", p[i]);
}
putchar('\n');
free(p);
return 0;
}
While here is C++ program by PaulMcKenzie that implements the same thing, although the use of pointer p is still frowned upon:
#include <vector>
#include <iostream>
using namespace std;
int main() {
std::vector<int> pV(2);
int *p = pV.data();
*(p + 0) = 8;
*(p + 1) = 9;
pV.resize(3);
p = pV.data();
*(p + 2) = 4;
for (int i = 0; i < 3; i++) {
cout << p[i] << " ";
}
}
As you can see, std::vector<int>::resize() takes the number of elements, no need to compute byte counts.
Using pointers and especially pointer arithmetic is not good practice in C++, a much simpler version is:
#include <vector>
#include <iostream>
using namespace std;
int main() {
std::vector<int> v(2);
v[0] = 8;
v[1] = 9;
v.resize(3);
v[2] = 4;
for (int i = 0; i < 3; i++) {
cout << v[i] << " ";
}
}
You could also use an enumerator for the printout.

Ok, I got the problem:
p = (int*)realloc(p, 3);
the size value I had specified was 3, it should have been 3 * sizeof(int)

Related

C++ Segmentation Fault (SIGSEGV)

I have a problem statement.
Given an even number A ( greater than 2 ), return two prime numbers whose sum will be equal to given number.
The following solution code runs fine for all small and medium inputs but fails for a very large input 16777214. It is a segmentation fault and I tried to read this article on it but I cannot figure out what my program is doing wrong, since it is working for other inputs or what should I fix here. I'm new to C++;
#include <iostream>
#include <vector>
using namespace std;
void form_sieve(int A, int* prime){
for(int c = 0; c < A; c++)
prime[c] = 1;
prime[0] = 0;
prime[1] = 0;
for(int p = 2; p * p <= A; p++){
if(prime[p] == 1){
// update all multiples of p
for(int i = p * p; i <= A; i += p)
prime[i] = 0;
}
}
}
void primesum(int A) {
// find prime numbers less than A
// use sieve method
int prime[A + 1];
form_sieve(A, prime);
vector<int> result;
// for(int c = 0; c <= A; c++)
// cout << prime[c] << "\n";
for(int i = 2; i <= A; i++){
if(prime[i]){
if(i + i == A){
result.push_back(i);
result.push_back(i);
break;
}
else if(prime[A - i]){
result.push_back(i);
result.push_back(A - i);
break;
}
}
}
// cout << result.size();
for(vector<int>::iterator ptr = result.begin(); ptr < result.end(); ptr++){
cout << *ptr << "\n";
}
// return result;
}
// Driver Code
int main()
{
primesum(16777214);
}
You need to allocate new memory.
A user2717954 already suggested using a vector for primes, which is the best way to fix this.
If you wanted to use arrays, you could change int prime[A+1] to int* prime = new int[A+1];. Then delete [] prime; after you're finished using it at the end of the function.
When I do this, the program doesn't segfault. You must allocate dynamic memory and clean up after you're done since the program doesn't know how much memory to allocate since the size A + 1 isn't known at compile-time.
However, vectors will, of course, resize as needed so you won't have to worry about dynamic memory.

add element to array of struct in C++ encountered "error no match for ‘operator=’"

My code was
#include <iostream>
#include <string>
using namespace std;
struct Numbers{
int a;
int b;
int c;
};
struct NumbersArray{
int size;
Numbers *numbers;
};
int main(){
NumbersArray numArr;
numArr.size = 10;
numArr.numbers = new Numbers[10];
for(int i = 0; i < 10; i++){
Numbers *num = new Numbers;
num->a = i * 3 + 0;
num->b = i * 3 + 1;
num->c = i * 3 + 2;
numArr.numbers[i] = num;
}
}
The basic idea is I create a struct called Numbers which contains 3 numbers and put it in a wrapper struct called NumbersArray.
And when I compile it with g++, I got error message
testArrayStruct.cc: In function ‘int main()’:
testArrayStruct.cc:23:27: error: no match for ‘operator=’ (operand types are ‘Numbers’ and ‘Numbers*’)
numArr.numbers[i] = num;
^
testArrayStruct.cc:23:27: note: candidate is:
testArrayStruct.cc:4:8: note: Numbers& Numbers::operator=(const Numbers&)
struct Numbers{
^
testArrayStruct.cc:4:8: note: no known conversion for argument 1 from ‘Numbers*’ to ‘const Numbers&’
Just ignore memory management here.
I cant figure it how to add elements to the array.
You are practising on the wrong things, and you will just
pick up bad habits this way. C++ thrive on value semantics,
focus on that:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct Numbers {
int a;
int b;
int c;
};
using NumbersArray = vector<Numbers>;
int main()
{
NumbersArray numArr;
numArr.resize(10);
for(int i = 0; i < 10; i++)
{
Numbers num;
num.a = i * 3 + 0;
num.b = i * 3 + 1;
num.c = i * 3 + 2;
numArr[i] = num;
}
}
It should be (ignoring your memory management as you asked):
numArr.numbers[i] = *num;
Instead of
numArr.numbers[i] = num;
since numArr.numbers[i] is of type Numbers while num is of type Numbers*.
EDIT:
The error actually tells you that there is no operator= to perform assignment of Numbers * to Numbers. So actually you could implement your own operator= which would perform such operation:
Numbers& operator=(Numbers& left, const Numbers * const right)
{
if (right != NULL) // or nullptr for C++11
{
left = *right;
}
return left;
}
With such implementation your original code would also compile.
One remark regarding the memory management. There is no real need to allocate new Numbers inside the for loop since you copy that content into the numArr.numbers anyway. So you could write it that way:
for(int i = 0; i < 10; i++){
numArr.numbers[i].a = i * 3 + 0;
numArr.numbers[i].b = i * 3 + 1;
numArr.numbers[i].c = i * 3 + 2;
}
how to add elements to the array
You can't.
When you said new Numbers[10] you created an array of ten default-initialized elements. An array can't resize itself after initialization.
It sounds like you should be using std::vector:
int main() {
std::vector<Numbers> numArr;
for(int i = 0; i < 10; i++) {
Numbers num;
num.a = i * 3 + 0;
num.b = i * 3 + 1;
num.c = i * 3 + 2;
numArr.push_back(num);
}
std::cout << "numArr contains " << numArr.size() << " elements." << std::endl;
}
Now you can add as many elements as you like and don't have to keep track of size etc. yourself. std::vector will resize itself when it needs to.
Try the following code. You are try to assign a pointer of an object to the object itself. The following one fixes it.
#include <iostream>
#include <string>
using namespace std;
struct Numbers{
int a;
int b;
int c;
};
struct NumbersArray{
int size;
Numbers **numbers;
};
int main(){
NumbersArray numArr;
numArr.size = 10;
numArr.numbers = new Numbers* [10];
for(int i = 0; i < 10; i++){
Numbers *num = new Numbers;
num->a = i * 3 + 0;
num->b = i * 3 + 1;
num->c = i * 3 + 2;
numArr.numbers[i] = num;
}
}
This is the important part of your error message:
error: no match for ‘operator=’ (operand types are ‘Numbers’ and ‘Numbers*’)
You are trying to assign a pointer to Numbers into a Numbers value. The rest of the error message is not helpful.
Assuming you don't want to change the NumbersArray class like all the other answers are suggesting, your inner loop should look like this:
for(int i = 0; i < 10; i++){
Numbers num;
num.a = i * 3 + 0;
num.b = i * 3 + 1;
num.c = i * 3 + 2;
numArr.numbers[i] = num;
}
Read about values and pointers in C++.

reserving continuous block using malloc

I'm trying to learn more about malloc() and need help clarifying the output. I want to reserve 10 bytes of memory and be able to access them individually but they must be in one block. Here is the code:
#include<iostream>
using namespace std;
#include<stdio.h>
#include<stdlib.h>
int main()
{
char neededbytes = 10;
char *p;
p = (char *)malloc(neededbytes * sizeof(char));
if(p==NULL)
{
cout<<"Error! memory not allocated.";
exit(0);
}
else
{
for (int i = 0; i < neededbytes; i++)
{
p[i] = 0;
}
for (int i = 0; i < neededbytes; i++)
{
cout<<"Address at index " << i << " is ";
cout<<&p+i<<endl;
}
}
free(p);
}
The output of the program shows that all addresses are 8 bytes apart. Shouldn't they be only one byte apart? Is there a way for me to know if char consumes 8 bytes on my architecture?
&p+i is the same as (&p)+(i), and since p has type char*, &p has type char**. As a result, adding i will actually add i * sizeof(char *) bytes to the address denoted by &p.
What you want is p + i, which will add i * sizeof(char) bytes to the address stored in p. In other words, you already have a pointer to contiguous data when you use malloc(). Of course, this is C++, so char * is handled specially by std::cout, std::cerr, and the std::ostream class in general. You'd need to do something like static_cast<void *>(p + i) rather than just p + i as you would use in C.
As others have stated, you should avoid using malloc() and free() in C++ when possible; C++ has the new[] and delete[] operators for your purpose.
cout<<&p+i<<endl; should just be cout<<static_cast<void*>(p+i)<<endl;
It's because you are using the address of operator, the offset will be i * sizeof(char *) in that case which on your system is apparently 8 * i bytes.
Try this instead
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int main()
{
char neededbytes = 10;
char *p;
p = static_cast<char *>(malloc(neededbytes));
if (p == NULL)
{
cout << "Error! memory not allocated.";
exit(-1);
}
for (int i = 0; i < neededbytes; i++)
p[i] = 0;
for (int i = 0; i < neededbytes; i++)
{
cout << "Address at index " << i << " is ";
cout << static_cast<void *>(p + i) << endl;
}
free(p);
}
You could look at the byte alignment of char in your compiler output settings but I bet char is always 1 byte. Try a few changes like this (I think you are accessing the wrong array element at &p+i) :
int main()
{
int neededbytes = 10;
char *p=NULL;
p = malloc(neededbytes * sizeof(char));
if(p==NULL)
{
cout<<"Error! memory not allocated.";
exit(0);
}
else
{
for (int i = 0; i < neededbytes; i++)
{
p[i] = 0;
}
for (int i = 0; i < neededbytes; i++)
{
cout<<"Address at index " << i << " is ";
// Dave cout<<p+i<<endl;
cout<<&(p+i)<<endl;
}
}
free(p);
}
NB: Dave shared the correct syntax of p+i. Thanks Dave
Change cout<<&p+i<<endl; to cout<<static_cast<void*>(p+i)<<endl;.
Here's a site that talks about memory alignment on GNU systems. It will always be 8(16 for 64 bit systems) byte aligned. There are some libc (stdlib.h) functions that can force alignment for you listed there though.
http://www.gnu.org/software/libc/manual/html_node/Aligned-Memory-Blocks.html

Pinter new operator C++

I was testing the new operator in C++ as the following:
#include <iostream>
using namespace std;
int main()
{
int *Q = new int[5];
Q[0] = 0;
Q[1] = 1;
Q[2] = 2;
Q[3] = 3;
Q[4] = 4;
for (int i = 0; i < 7; i++)
{
cout << "Q[" << i << "] = " << Q[i] << endl;
}
return 0;
}
If you notice, in the for loop I am exceeding the limit of the pointer and I was expecting an stack over flow type of error; but instead of that it just printed what ever these two extra locations have.
Does any one have explanation about this ?
Yes, what is happening is that your program is "walking off" the end of an array, and is printing out garbage. "Garbage" in this context can be anything in the computer (memory, etc.). It does not have protections against this like Java or Python does.

C and C++ difference behavior [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I have created two template project in Eclipse with CDT plugin(one is C project, another C++), and have compiled two very similar projects(as for me) but I get absolutely different console outputs. Why this outputs so different?
C code:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int numbers[5];
int * p;
p = numbers; *p = 10;
p++; *p = 20;
p = &numbers[2]; *p = 30;
p = numbers + 3; *p = 40;
p = numbers; *(p+4) = 50;
int n;
for (n=0; n<5; n++)
printf("%c ",numbers[n]);
return EXIT_SUCCESS;
}
output
some garbage
C++ code:
#include <iostream>
using namespace std;
int main() {
int numbers[5];
int * p;
p = numbers; *p = 10;
p++; *p = 20;
p = &numbers[2]; *p = 30;
p = numbers + 3; *p = 40;
p = numbers; *(p+4) = 50;
for (int n=0; n<5; n++)
cout << numbers[n] << " ";
return 0;
}
output
10, 20, 30, 40, 50
You are printing int as char in C.
Change
printf("%c ",numbers[n]);
to
printf("%d ",numbers[n]);
You're trying to output the numbers as characters, causing your odd output.
The code worked fine for me as this.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int numbers[5];
int * p;
p = numbers; *p = 10;
p++; *p = 20;
p = &numbers[2]; *p = 30;
p = numbers + 3; *p = 40;
p = numbers; *(p+4) = 50;
int n;
for (n=0; n<5; n++)
printf("%d ",numbers[n]);
return EXIT_SUCCESS;
}
Note the %d, rather than %c
You print the ASCII value of the integers. Try
printf("%i", numbers[n])
instead of
printf("%c", numbers[n])
You need %d to print integer and %c to print char in C
http://www.cplusplus.com/reference/cstdio/printf/
Look at your below statement
printf("%c ",numbers[n]);
You are using %c to print int, which is wrong.
To be specific printf has been borrowed from C and has some limitations. The most common mentioned limitation of printf is type safety, as it relies on the programmer to correctly match the format string with the arguments. The second limitation that comes again from the varargs environment is that you cannot extend the behavior with user defined types. The printf knows how to print a set of types, and that's all that you will get out of it. Still, it for the few things that it can be used for, it is faster and simpler to format strings with printf than with c++ streams.