I have allocated a block of memory as (char *), in which I want to be able to store an integer.
char * arr = new char[50];
int num = 9;
for(int i = 0; i < sizeof(int); i++)
{
*((int *)arr) = arr[i];
}
memcpy(&arr, &num, sizeof(num));
cout<<"Contents of arr: "<<arr<<endl;
I seem to be getting a segmentation fault whenever I compile however. How can I fix this? Thank you!
The for loop is unnecessary. I'm not sure what it is trying to accomplish. The memcpy is ok except that you're taking the address of arr which is already a pointer. This will work:
char * arr = new char[50];
int num = 9;
memcpy(arr, &num, sizeof(num));
cout<<"Contents of arr: "<< ((int *)arr) <<endl;
Perhaps your for loop was trying to do this:
char * arr = new char[50];
int num = 9;
*((int *)arr) = num;
cout<<"Contents of arr: "<< ((int *)arr) << endl;
That would be ok, too.
Edit: The contents of the array are not printable directly, at least not with any meaning (and may crash because of no zero termination). Assuming you want it to look like an integer, I've edited the code above. C++ purists will probably object to using a C style cast instead of reinterpret_cast<>, but that's a separate issue.
Related
I have some code like this :
int n;
cin >> n;
int array[n];
for (int i = 0; i < n; ++i) {
cin >> array[i];
}
int tmp[n - 1];
tmp[0] = 1;
With input : 1 10 I found that the value of array[0] was changed , instead of 10 it has the same with tmp[0].
Then I realized with that input the length of tmp[] became zero. So I print the address of array[] and tmp[] with:
printf("%d\n %d\n", array, tmp);
and found they had the same address.
I want to figure out what will happen if an array has a length of 0; so I tried this:
int array[1];
array[0] = 10;
int tmp[0];
tmp[0] = 1;
address:
array[]: 1363909056
tmp[] : 1363909052
It looks just like the previous code (except the input part). But tmp[0] and array[0] has different values and address now.
And I'm really confused that tmp has smaller address then array.
So my question is:
What will happen if I declare an array of length zero?
Why these two codes works different? (they look the same to me :) )
This is called "undefined behavior". After declaring, in your case
int tmp[0];
The next thing that happens is:
tmp[0]=1;
Since tmp[0] does not exist, this is undefined behavior. Your problem is not that the array was declared with size 0 (that's not exactly kosher on its own merits, but is not the issue here), but the undefined behavior as a result of overwriting memory past the end of the array.
I have a homework problem that I'm working out. Me and some other students are pretty sure that our teacher misspoke, but maybe not. I checked through a bit of the questions here already and can't really find a way to use pointers to create what is essentially an array. The instructions read as follows.
Rewrite the following program to use pointers instead of arrays:
The code is this
int main()
{
int salary[20];
int i;
for (i = 0; i < 20; i++)
{
cout << "Enter Salary: ";
cin >> salary[i];
}
for (i = 0; i < 20; ++i)
salary[i] = salary[i] + salary[i] / (i + 1);
return 0;
}
My solution was this:
int main()
{
int* salary_pointer = new int;
for (int i = 0; i < 20; i++)
{
cout << "Enter Salary: ";
cin >> *(salary_pointer + i);
}
for (int i = 0; i < 20; ++i)
{
*(salary_pointer + i) = *(salary_pointer + i) + *(salary_pointer + i) / (i + 1);
cout << *(salary_pointer + i) << endl;
}
delete salary_pointer;
return 0;
}
It keeps flagging a segmentation fault at about salary number 13
My main purpose (because I'm almost positive my teacher wrote this down wrong) is to understand more about pointers, so any and all tips and tricks for learning these confusing things would be greatly appreciated. Thank you all!
Use
int* salary_pointer = new int[20];
instead, as you allocate 20 ints, not just one. Then, delete the dynamic array using
delete[] salary_pointer;
instead of delete salary_pointer. Be also careful here:
salary[i] / (i + 1);
If the operands are int, then you end up with truncation. Use salary[i]/(i + 1.) in case you want your result as a double (in which case you better make salary an array of doubles or a pointer to double so you don't have this issue anymore).
Your teacher did not misspeak. You have bugs in your program.
How many elements did you allocate?
How many elements are you trying iterate through and dereference?
How many elements did you free?
You're getting a seg fault, because you are dereferencing memory you did not allocate.
I'd be more specific, but giving too much away won't help you get better when it comes to homework.
This kind of manual memory management is done away with later when you will be using STL containers for the most part, but the relationship between pointers and arrays, and the ability to do pointer arithmetic is important.
Why is your teacher wrong?
Here is what is happening. You are creating a pointer to a SINGLE integer. As you iterate through your for loop what you are doing is actually overwriting memory that is possibly, and I STRESS possibly, being used by other bits of your program. This causes undefined behavior up to and including a crash.
Redo your memory allocation and your access violation should go away. Also, use a variable to hold your '20'. Something like const int MAX_SALARIES = 20. Learn to do this as it will often save you TONS of headaches in the future.
In this statement
int* salary_pointer = new int;
there is allocated only one object of type int.
And as there is used the division operation it is better to use type float instead of int for the array.
I would suggest the following solution. It uses only pointers.
#include <iostream>
int main()
{
const size_t N = 20;
float *salary = new float[N];
^^^^^^^^^^^^^^^^^^^^^^^^^^
for ( float *p = salary; p != salary + N; ++p )
{
std::cout << "Enter Salary: ";
std::cin >> *p;
}
for ( float *p = salary; p != salary + N; ++p )
{
*p += *p / ( p - salary + 1 );
}
delete [] salary;
^^^^^^^^^^^^^^^^
return 0;
}
#include<stdio.h>
#include<conio.h>
unsigned * bin(unsigned n) {
unsigned a[16];
int i = 0, j = 0;
for (i = 0; i < 16; i++) {
a[i] = n & 0x1;
n = n >> 1;
}
return a;
}
void main() {
unsigned n = 5;
int i = 0;
unsigned * a = bin(n);
for (i = 15; i >= 0; i--) {
printf("%d\n", (*(a + i)));
}
getch();
}
Please help this binary conversion does not work. I'm trying to calculate x^n using binary conversion.
can anybode help??
You are returning a pointer to a local variable. This variable is stored on the stack, and will not be valid after the function returns.
Dereferencing this pointer will lead to undefined behavior.
The solution is to either make the variable static, or pass in the array as an argument to the function, or (as noted in a comment by James Kanze) use a type that copies the contents.
you can not return a local array defined in the function in this way.
The content of the array will be erased when the function finish the execution.
instead of using
unsigned a[16];
you can use the following:
unsigned *a =malloc(16 * (sizeof *a));
And do not forget in your main to free the memory allocated for a when the a array become useless in your program. you can free the array with:
free(a);
Actually, this is a typical case where using new (or malloc) is a pretty bad choice. However, as others have said, returning a pointer to a local array is bad.
Instead, pass in an array:
void bin(unsigned n, unsigned a[]) {
int i = 0;
for (i = 0; i < 16; i++) {
a[i] = n & 0x1;
n = n >> 1;
}
}
and in main:
unsigned a[16];
bin(n, a);
Now you have no need to allocate or return an array from bin.
Ok, I know that this is invalid
char char_A = 'A';
const char * myPtr = &char_A;
*myPtr = 'J'; // error - can't change value of *myP
[Because we declared a pointer to a constant character]
Why is this valid?
const char *linuxDistro[6]={ "Debian", "Ubuntu", "OpenSuse", "Fedora", "Linux Mint", "Mandriva"};
for ( int i=0; i < 6; i++)
cout << *(linuxDistro+i)<< endl;
*linuxDistro="WhyCanIchangeThis";// should result in an error but doesnt ?
for ( int i=0; i < 6; i++)
cout << *(linuxDistro+i)<< endl;
Thanks for looking!
You write
*linuxDistro = "WhyCanIchangeThis";
which is perfectly valid, because the declaration of linuxDistro was
const char *linuxDistro[6];
i. e. it's an array of 6 pointers to const char. That is, you can change the pointers themselves, just not the characters pointed to by those pointers. I. e., you can not compile
*linuxDistro[0] = 'B';
to obtain the string "Bebian", becuse the strings contain constant characters...
What you probably want is an array of constant pointers to constant characters:
const char *const linuxDistro[6];
*linuxDistro is still a pointer, it is linuxDistro[0], *linuxDistro="WhyCanIchangeThis" it just change the pointer to point to a new address, not to modify the content in the old address, so it is OK.
If you write **linuxDistro='a', it should error.
because the pointer is a variable that stores a memory address, if a pointer is const the pointer keeps storing the same memory address, so the value of the pointer itself can't change, but you are saying nothing about the value pointed by the pointer, according to what you have, chaging the pointed value it's an allowed operation.
because char is not char[], so when you access to * of char[] you access the first element of it (Debian).
when you shift pointer (e.g. +1 it) you access next element of array
here is good example for better understanding
#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;
}
this will output:
10, 20, 30, 40, 50,
I have created 2 dynamic arrays in the main function. I have passed both of them to the function by reference. Then I copy data from smaller dynamic array to the larger dynamic array. I delete the smaller dynamic array. Assign the address of the larger dynamic array to the smaller dynamic array. Now ideally the arr array should have size of 10. However, when I try to print the 6th element of the array in the main, it crashes. Please have a look at the code below:
#include <iostream>
#include <string>
using namespace std;
void func(string * arr, string * brr);
int main()
{
string* arr = new string[5];
arr[0] = "hello0";
arr[1] = "hello1";
arr[2] = "hello2";
arr[3] = "hello3";
arr[4] = "hello4";
string* brr = new string[10];
func(arr, brr);
for(int i = 0; i < 6; i++)
cout << arr[i] << endl;
return 0;
}
void func(string * arr, string * brr)
{
for(int i = 0; i < 5; i++)
brr[i] = arr[i];
for(i = 0; i < 5; i++)
cout << brr[i] << endl;
delete []arr;
arr = brr;
arr[5] = "hello5";
}
This line has absolutely no effect for the caller:
arr = brr;
So after the call, arr points exactly where it used to point before - to a now invalid memory area (because you deleted it).
If this would be a C question, I would advise you to use a pointer to a pointer (string **arr). However, I feel this is nasty in a C++ program. Maybe you want to use a reference somewhere ?
Set this signature for the function
void func(string * & arr, string * & brr)
#cnicutar correctly diagnosed the problem; you'll either need to pass arr by reference (reference to the POINTER, not the array), of have fund return the new value of arr, which the caller can assign.