pragram giving error when character pointer is assigned null value? - c++

I have following two versions of code
correctly working program
#include<iostream.h>
#include<string.h>
void main()
{
const char *q="+\0";
char *p=""; //working correct with ""
strncpy(p,q,2);
cout<<p;
}
Program giving error
#include<iostream.h>
#include<string.h>
void main()
{
const char *q="+\0";
char *p=NULL; //Program gives error abnormal termination when *p=NULL or *p="\0"
strncpy(p,q,2);
cout<<p;
}
I am not understanding the two different behavior of the char *p in these code samples.
Please help.

No part of your program is correct. The memory that contains string literals must not be modified, so you must never copy to the location p.
You must only access memory that you personally obtained for your own use, like so:
char p[500];
strncpy(p, "+\0", 2); // OK, *p is yours

I believe you actually mean when p == NULL (from your comment)
*p == NULL just means p points to some address which holds the value 0.
In other words *p == NULL and p == NULL are two completely different things.
So if you tried to edit the memory where p points to, and that memory is address 0x0000 (also known as NULL) that is pretty much guaranteed to fail, because you likely do not own this memory.
When I say own, I mean your program has allocated memory at this location. If you write char *p = new char; then your program allocates some sizeof(char) bytes of memory. And now if you modify the value of *p that is okay because you have been given the memory (by the operating system or whatever).

Related

What happens when assigning a value to non-allocated memory?

int main()
{
char* p = new char('a');
*reinterpret_cast<int*>(p) = 43523;
return 0;
}
This code runs fine but how safe is it? It should have only allocated one byte of memory but it doesn't seem to be having any problem filling 4 bytes with data. What can happen with the other 3 bytes that are not allocated?
char* p = new char('a');
ASCII code of 'a' is 97, so this is equivalent to:
char* p = new char(97);
Single character (1 byte) space is allocated with *p='a'
Now, you are trying to put more than 1-byte value, that's certainly risky, even if this works, I mean runs without any segmentation fault. You are overwriting some other parts of memory that you don't own or even if own, must be for some other purpose.
The code is not safe. Your program has undefined behaviour. Anything at all could happen.
The code causes heap buffer overflow. You're overriding memory which you don't own and can be in use in other parts of the program.

Segfault Pointers [duplicate]

This question already has an answer here:
C++ Struct Pointer Segfault
(1 answer)
Closed 9 years ago.
I'm new to C++ and pointers and wrote a simple cpp below. I keep on getting a seg fault, but I'm not sure why.
int main() {
int *x = 0;
*x = 8;
return 0;
}
Your integer pointer is null. See this line:
int *x =0
On that line you're setting the memory address of your integer pointer to zero (i.e. nullptr). What I expect you wanted to do is set the value to zero, in which case you'd need to do this:
int main() {
int *x = new int(0);
*x = 8;
return 0;
}
You've declared a pointer to an integer and set it to 0. You haven't actually allocated an integer anywhere. When you assign 8 to the dereferenced pointer, you're trying to write to the memory at location 0. All modern operating systems read and write product the memory at address 0 and anywhere near it to prevent this kind of 'null pointer error'.
Think of memory on a computer as a sheet of graph paper. Each square on the paper has an address, which is the number of squares that came before it. Pointers are for storing these addresses. An int is an actual value, like '5 apples' or '12 downvoting asshats'. These are the values that are stored by writing a number inside one of the rectangles.
However, the OS that manages the system knows that one of the most common kinds of errors people make is forgetting to set up a pointer properly and attempting to write numbers at the very start of the graph paper, so it's designed the graph paper to give you an electric shock if you try to write a number in any of the first few boxes. This is your segmentation fault.
To fix the issue you can either declare an integer on the stack
int i;
int * x = &i;
Declaring something on the stack means the memory will automatically be freed when it leaves scope, i.e. the end of the function.
On the other hand you can allocate a pointer on the heap
int * x = new int;
this means that you're personally responsible for making sure that you free the memory at some later point.
delete x;
Otherwise you're creating a memory leak.
When you define int *x = 0, what you're telling the compiler is "create a integer pointer, x, and set where it points to to 0 (NULL)". What you need to do instead is dynamically create a new pointer. This can be achieved by doing int *x = new int; Then you can change its value. After using it, you should delete it using delete x; to free up its memory.
int *x = 0;
You made an int pointer called x which points to the memory at location 0.
*x = 8;
You tried to write the value 8 into the memory at location 0, which was stored in x. Since this memory is not owned by you, the OS terminated you.
Let's break this down a bit:
int *x = 0
this line creates a pointer called x and points it to NULL (or nowhere)
*x = 8
There is an immediate issue here as soon as you "dereference" x, meaning asking for the spaces associated what x points to.
Since you pointed x at NULL you're asking for the int located at NULL. This is illegal as NULL is an invalid memory space causing a seg-fault.

Usage of number object in malloc

I am new to programming and I am trying to understand the difference between
A = (char * ) malloc(sizeof(char)*n);
and
A = (char * ) malloc(sizeof(char));
or
A = new char [n];
and
A = new char;
What is the default memory that a compiler is allocating to this pointer, when I do not specify the number of objects of particular data type.
Also when I declare
A = new char [n];
cout << A[n+1];
it does not give me a segmentation fault.
Should It not give segmentation fault because I am trying to access memory beyond what has been allocated for the Array.
Memory is not "allocated to this pointer", it's allocated and then you get a pointer to the memory.
This:
char *a = malloc(sizeof(char) * n);
is the same as
char *a = malloc(n);
since sizeof(char) is always 1. They both allocate space for n characters worth of data, and return a pointer to the location where the first character can be accessed (or NULL on failure).
Also, the casts are not needed in C, you should not have any.
Since sizeof(char) is 1, the second call is equivalent to:
char *a = malloc(1);
which means it allocates a memory block of size 1. This is of course distinct from the pointer to that memory block (the value that gets stored in the pointer variable a). The pointer is most likely larger than 1 char, but that doesn't affect the size of the block.
The argument to malloc() specifies how many chars to allocate space for.
I ignored the new usage, since that is C++ and the question is tagged C.
A = (char * ) malloc(sizeof(char)*n);
This allocates space for n characters.
A = (char * ) malloc(sizeof(char));
This allocates memory for 1 character.
Every call to malloc allocates memory in the heap.
The other code is C++, and it's exactly the same, except that it will use stack memory if A is a local variable. Accessing A[n+1] may or may not yield a segfault. A[n+1] can reference a memory address that you are allowed to use. Segfault happens when you go out of the region of memory you can access, and the way it works is that there is a "red zone" from which it is considered you accessed invalid memory. It may be the case that A[n+1] just isn't "invalid enough" to trigger a segfault.
allocate space for N characters (N should be some positive integer value here)
char *ma = (char * ) malloc(N);
char *na = new char [N];
don't forget to release this memory ...
delete [] na;
free(ma);
allocate space for a single character
char *mc = (char * ) malloc(sizeof(char));
char *nc = new char;
Now, as the others have pointed out, you tagged this C, but half your code is C++. If you were writing C, you couldn't use new/delete, and wouldn't need to cast the result of malloc.
Oh, and the reason you don't get a segmentation fault when you read off the end of your array is that this is undefined behaviour. It certainly could cause a SEGV, but it isn't required to check, so may appear to work, at least some of the time, or fail in a completely different way.
Well, the compiler doesn't allocate memory for the data. Only the pointer which is either 4 or 8 bytes depending on your architecture.
There is no difference between the first two and the last two in terms on functionality. Most C++ libraries I've seen use malloc internally for new.
When you run the code to allocate n characters and you print out the n + 1th character, you aren't getting a segmentation fault most likely because n isn't a multiple of some number, usually 8 or 16. Here's some code on how it might do that:
void* malloc(size_t size) {
if (size & 0x7 != size)
size = size & 0x7 + 1;
return _malloc(size);
}
So, if you requested, say, 5 bytes, malloc would actually allocate, with that code, 8 bytes. So, if you request the 6th byte (n + 1), you would get garbage, but it is still valid memory that your program can access.

Do I need to use the new operator in C++

what is the difference between the following block of code :
#include<iostream>
using namespace std;
int main()
{
int *p;
float *q;
cout<<p<<"\n"<<q;
}
and this code :
#include<iostream>
using namespace std;
int main()
{
int *p;
float *q;
p = new int;
q = new float;
cout<<p<<"\n"<<q;
}
In both the cases the pointers are allocated some memory right?
Then why should i use the new operator?
No, int *p and float *p declare pointers, but they are not initialised, so they each point to a random address in memory. In particular, they do not point to memory space allocated to your program.
The second piece of code correctly allocates memory and stores the address of that memory in the two pointers. However, note that your code never de-allocates the memory, so you have a memory leak. You'd have to use delete p and delete q at the end of the program to avoid this.
To answer the question in your title a bit more directly: no, you do not have to use the new operator very often in C++; in fact, in well written code you usually use it quite rarely.
In this case, rather than using pointers at all, you would typically want to just define the int and float using the auto storage class, without defining any pointers or using new at all. While you're at it, most code shouldn't have using namespace std; in it either. Fixing those, you could end up with something like this:
#include<iostream>
int main()
{
int p = 1;
float q = 2.0f;
std::cout<<p<<"\n"<<q;
}
If your code has new and/or T *xxx very often (where T is some type and xxx is some identifier) chances are pretty good that it's not really a question of whether you're doing something wrong, only of how many things and how badly wrong.
In the first block of code, memory is allocated for the pointers themselves, but no memory is allocated which they can point to and validly use. The address that is printed out is not safe for your program to use.
The "pointer" variable does already being allocated in main() stack, 4 bytes in 32-bit or 8 bytes in 64-bit machines. The memory storage for int and float, which are pointed by p and q respectively, are not allocated yet in the first case. Your cout just prints out the memory address of p & q, not the value where p or q points to.

why does this fail

i am stuck and unable to figure out why this is the following piece of code is not running .I am fairly new to c/c++.
#include <iostream>
int main(){
const char *arr="Hello";
const char * arr1="World";
char **arr2=NULL;
arr2[0]=arr;
arr2[1]=arr1;
for (int i=0;i<=1;i++){
std::cout<<arr2[i]<<std::endl;
}
return 0;
}
where as this is running perfectly fine
#include <iostream>
int main(){
const char *arr="Hello";
const char * arr1="World";
char *arr2[1];
arr2[0]=arr;
arr2[1]=arr1;
for (int i=0;i<=1;i++){
std::cout<<arr2[i]<<std::endl;
}
return 0;
}
Why is this? and generally how to iterate over a char **?
Thank You
char *arr2[1]; is an array with one element (allocated on the stack) of type "pointer to char". arr2[0] is the first element in that array. arr2[1] is undefined.
char **arr2=NULL; is a pointer to "pointer to char". Note that no memory is allocated on the stack. arr2[0] is undefined.
Bottom line, neither of your versions is correct. That the second variant is "running perfectly fine" is just a reminder that buggy code can appear to run correctly, until negligent programming really bites you later on and makes you waste hours and days in debugging because you trashed the stack.
Edit: Further "offenses" in the code:
String literals are of type char const *, and don't you forget the const.
It is common (and recommended) practice to indent the code of a function.
It is (IMHO) good practice to add spaces in various places to increase readability (e.g. post (, pre ), pre and post binary operators, post ; in the for statement etc.). Tastes differ, and there is a vocal faction that actually encourages leaving out spaces wherever possible, but you didn't even do that consistently - and consistency is universially recommended. Try code reformatters like astyle and see what they can do for readability.
This is not correct because arr2 does not point to anything:
char **arr2=NULL;
arr2[0]=arr;
arr2[1]=arr1;
correct way:
char *arr2[2] = { NULL };
arr2[0]=arr;
arr2[1]=arr1;
This is also wrong, arr2 has size 1:
char *arr2[1];
arr2[0]=arr;
arr2[1]=arr1;
correct way is the same:
char *arr2[2] = { NULL };
arr2[0]=arr;
arr2[1]=arr1;
char **arr2=NULL;
Is a pointer to a pointer that points to NULL while
char *arr2[1];
is an array of pointers with already allocated space for two items.
In the second case of the pointer to a pointer you are are trying to write data in a memory location that does not exist while in the first place the compiler has already allocated two slots of memory for the array so you can assign values to the two elements.
If you think of it very simplistically, a C pointer is nothing but an integer variable, whose value is actually a memory address. So by defining char *x = NULL you are actually defining a integer variable with value NULL (i.e zero). Now suppose you write something like *x = 5; This means go to the memory address that is stored inside x (NULL) and write 5 in it. Since there is no memory slot with address 0, the the entire statement fails.
To be honest it;s been ages since I last had to deal with such stuff however this little tutorial here, might clear the motions of array and pointers in C++.
Put simply the declaration of a pointer does NOT reserve any memory, where as the declration of a array doesn't.
In your first example
Your line char **arr2=NULL declares a pointer to a pointer of characters but does not set it to any value - thus it is initiated pointing to the zero byte (NULL==0). When you say arr2[0]=something you are attempting to place a valuei nthis zero location which does not belong to you - thus the crash.
In your second example:
The declaration *arr2[2] does reserve space for two pointers and thus it works.