How to eleminate access voilation writing location - c++

I am dealing with arrays of size ((128*75)*(128*75)) in C.Whenever I declared the array as global,there is no issue like
#include<stdio.h>
float buf[(128*75)*(128*75)]
int main()
{
//using buf in different functions works fine
}
But whenever i declared it using malloc and using in main() getting access violation writing location error,
#include<stdio.h>
int main()
{
float * buf;
buf = malloc((128*75)*(128*75));
//using buf in different functions gives error
}
What is the reason for it?

malloc(x) only reserves x bytes, not x floats.
The global arrays is indeed 128*75*128*75 floats in size. The malloc-ed buffer is only 128*75*128*75 bytes in size, i.e. can only contain one fourth of the required number of floats (assuming a float is 4 bytes on your platform).
That is why you probably access beyond the limits of the malloc-ed buffer and get a segfault/access violation or whatever it is called on your platform.
You can use calloc() or you can use a size of 128*75*128*75*sizeof(float) as argument to malloc().

first, why not do:
int size = 128*75*128*75;
float buf[size];
second, check buf != NULL before using it, because malloc may have failed (if malloc failed, you will get NULL as return value - so you may miss that, if the array you tried to use is too big - you'll get compilation error - can't miss)
third, use sizeof inside malloc: buf = malloc(sizeof(float)*size); (as said by others, malloc allocates bytes and when declaring array - the compiler knows the type of element you want, so it gives you array with that size - meaning int a[2] size is 2*sizeof(int) but malloc(2) size is 2 bytes which is smaller

Related

How to free a dynamically allocated memory to an array inside a struct?

I'm trying to free the memory of the allocated array inside struct _Stack, but the program keeps crashing
typedef struct _Stack
{
int top;
unsigned int capacity;
int* arr;
}_Stack;
_Stack* createStack(int capacity)
{
_Stack* stack = (_Stack*) malloc(sizeof(_Stack));
stack->capacity = capacity;
stack->top = -1;
stack->arr = (int*) malloc(sizeof(stack->capacity * sizeof(int)));
return stack;
}
I'm using this function to free the memory, but the program crashes here.
// I have a problem here.
void stack_free(_Stack* stack)
{
free(stack->arr);
free(stack);
}
Change this:
stack->arr = (int*) malloc(sizeof(stack->capacity * sizeof(int)));
to this:
stack->arr = (int*) malloc(stack->capacity * sizeof(int));
since you want the size of the array to be equal to stack->capacity * sizeof(int), and not equal to the size of that expression.
Your program must have invoked Undefined Behavior somewhere in code not shown in the question (because of the wrong size malloc'ed), that's why it crashes later.
PS: Since you use C++, consider using new instead (and delete, instead of free()).
sizeof(stack->capacity * sizeof(int)) in your call to malloc is wrong. Instead of the size of the array, it gives the size of the number used to represent the size of the array. You probably want stack->capacity * sizeof(int).
Another possible problem is that in C you should not cast the return value of malloc, since it can hide other mistakes and cause a crash. See Do I cast the result of malloc?
In C++ you will have to do it, because of the stricter type checking in C++, but it can still hide problems.
These are the problems I see with the code you have shown. However, remember that errors in malloc and free are not necessarily caused by the actual line where they are detected. If some part of your program damages the malloc system's internal data structures, for example by a buffer overrun, the problem can manifest in a much later call to malloc or free, in a completely different part of the program.

Segmentation fault during the initialization of array

I have seen segmentation fault sometimes during the initialization of an array with huge size.
For ex:
#include<iostream>
#include<limits>
using namespace std;
int main()
{
string h;
cin >> h;
int size=h.size();
cout << size << endl;
int arr[size][size];
cout << arr[0][0]<<endl;
arr[0][0]=1;
cout << arr[0][0]<<endl;
return 0;
}
When the user input is a small string lets say "sample" the program is working fine.
When the user input is a big string where the size is for ex. >1500.Segmentation is seen during the initialization of the array int arr[size][size];
What can be the issue?Is there any problem in initializating the array like the one above.
I think you are out of memory with those initializations, causing a stack overflow. I recommend to allocate it on the heap or by using a std:vector. See here: Segmentation fault on large array sizes
I think an array's size must always be a compile-time constant in C++ i.e. the value of your 'size' variable must be known at compile time.
If you want dynamic storage, use std::vector
MSDN states that the default stack size on Windows is 1 MB - in case of 1500 elements in each dimension your array would take up 1500 * 1500 * 4 bytes = 9000000 bytes = 8.58 megabytes, not sure about Linux (this states it to be 8 MB) - I guess it depends on the compiler and distributive. So either:
1) If you know that there is a limit for the string length increase the stack size accordingly with the /STACK linker flag on Windows or like posted in this answer on Linux
2) Allocate the array on heap - if you don't want to mess around with memory allocations std::vector or std::unique_ptr can be used as a container

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.

Visual C++ Array Size Crash [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Stack overflow visual C++, potentially array size?
This code is simply meant to read values from a binary file into the array DataBuffer. When the size of DataBuffer is greater than or equal to 515000, it simply crashes. I am developing this in Visual C++ 2010 on Windows 7. The function cbFileRead() is something whose source code I can not access. cbFileRead() expects DataBuffer to be of the type USHORT*.
#include <stdio.h> // printf()
#include "cbw.h" // cbFileRead()
int main(int argc, char* argv[]) {
// Declarations
char* FileName = argv[1];
long FirstPoint = 0;
long NumPoints;
// Set data collection sizes
const long chunkSize = 515000;
NumPoints = chunkSize; // Number of points to be read into mem
WORD DataBuffer[chunkSize-1];
// Get data
cbFileRead(FileName, FirstPoint, &NumPoints, DataBuffer);
printf("Completed on data point %d whose value is %d\n", NumPoints, DataBuffer[chunkSize-1]);
return 0;
}
What reasons are there for this crashing? I would expect the array size to be able to go much higher.
The printf() is going beyond the end of the array DataBuffer, as it has chunksize - 1 elements so the last element is chunksize - 1 - 1. The function cbFileRead() is (possibly) misinformed of the number of elements in DataBuffer also.
EDIT:
As others have already stated, the default stack size is 1MB. The size of the DataBuffer array is 2 * 515000 which equals 1030000, which leaves 18576 free bytes on the stack. cbFileRead() could easily be declaring a large buffer on the stack for reading from file. As suggested by everyone else, allocate the DataBuffer on the heap using new[] (and delete[] to free) or use vector<WORD>.
The default stack reservation size used by the linker is 1 MB. To
specify a different default stack reservation size for all threads and
fibers, use the STACKSIZE statement in the module definition (.def)
file.
Microsoft Dev Center - Thread Stack Size
Or you can allocate the memory dynamically with the new keyword.
Your stack size may not be large enough to handle local data of that size (assuming this is what you mean by "crash"):
// use dynamic allocation instead of stack local
WORD *DataBuffer = new WORD[chunkSize];
cbFileRead(FileName, FirstPoint, &NumPoints, DataBuffer);
// ...use DataBuffer...
// deallocate DataBuffer when done
delete[] DataBuffer;
On most platforms, including Windows, local variables are stored on a stack, which has a limited size - in this case, it looks like it's around 1MB. There's probably a way to increase that size if you really need to, but it would be better to allocate large arrays dynamically:
#include <vector>
std::vector<WORD> DataBuffer(chunkSize); // guessing that "chunkSize-1" was an error
cbFileRead(FileName, FirstPoint, &NumPoints, &DataBuffer[0]);
printf("Completed on data point %d whose value is %d\n",
NumPoints, DataBuffer[chunkSize-1]);
Note that, if the array size is actually supposed to be chunkSize-1, then the last element would be DataBuffer[chunkSize-2], since arrays are indexed from zero.

Length of a BYTE array in C++

I have a program in C++ that has a BYTE array that stores some values. I need to find the length of that array i.e. number of bytes in that array. Please help me in this regard.
This is the code:
BYTE *res;
res = (BYTE *)realloc(res, (byte_len(res)+2));
byte_len is a fictitious function that returns the length of the BYTE array and I would like to know how to implement it.
Given your code:
BYTE *res;
res = (BYTE *)realloc(res, (byte_len(res)+2));
res is a pointer to type BYTE. The fact that it points to a contiguous sequence of n BYTES is due to the fact that you did so. The information about the length is not a part of the pointer. In other words, res points to only one BYTE, and if you point it to the right location, where you have access to, you can use it to get BYTE values before or after it.
BYTE data[10];
BYTE *res = data[2];
/* Now you can access res[-2] to res[7] */
So, to answer your question: you definitely know how many BYTEs you allocated when you called malloc() or realloc(), so you should keep track of the number.
Finally, your use of realloc() is wrong, because if realloc() fails, you leak memory. The standard way to use realloc() is to use a temporary:
BYTE *tmp;
tmp = (BYTE *)realloc(res, n*2);
if (tmp == NULL) {
/* realloc failed, res is still valid */
} else {
/* You can't use res now, but tmp is valid. Reassign */
res = tmp;
}
If the array is a fixed size array, such as:
BYTE Data[200];
You can find the length (in elements) with the commonly used macro:
#define ARRAY_LENGTH(array) (sizeof(array)/sizeof((array)[0]))
However, in C++ I prefer to use the following where possible:
template<typename T, size_t N>
inline size_t array_length(T data[N])
{
return N;
};
Because it prevents this from occurring:
// array is now dynamically allocated
BYTE* data = new BYTE[200];
// oops! this is now 4 (or 8 on 64bit)!
size_t length = ARRAY_LENGTH(data);
// this on the other hand becomes a compile error
length = array_length(data);
If the array is not a fixed size array:
In C++, raw pointers (like byte*) are not bounded. If you need the length, which you always do when working with arrays, you have to keep track of the length separately. Classes like std::vector help with this because they store the length of the array along with the data.
In the C way of doing things (which is also relevant to C++) you generally need to keep a record of how long your array is:
BYTE *res;
int len = 100
res = (BYTE *)realloc(res, (byte_len(len)));
len += 2;
res = (BYTE *)realloc(res, (byte_len(len)));
An alternative in the C++ way of doing things s to use the std::vector container class; a vector has the ability to manage the length of the array by itself, and also deals with the issues of memory management..
EDIT: as others have pointed out the use of realloc here is incorrect as it will lead to memory leaks, this just deals with keeping track of the length. You should probably accept one of the other replies as the best answer
Given the information you seem to have available, there is no way to do what you want. When you are working with arrays allocated on the heap, you need to save the size somewhere if you need to work with it again. Neither new nor malloc will do this for you.
Now, if you have the number of items in the array saved somewhere, you can do this to get the total size in characters, which is the unit that realloc works with. The code would look like this:
size_t array_memsize = elems_in_array * sizeof(BYTE);
If you are really working with C++ and not C I would strongly suggest that you use the vector template for this instead of going to malloc and realloc. The vector template is fast and not anywhere near as error prone as rolling your own memory management. In addition, it tracks the size for you.
When you allocate the pointer initially you also need to keep track of the length:
size_t bufSize = 100;
BYTE* buf = malloc(sizeof(BYTE ) * bufSize);
When you re-allocate you should be carefull with the re-alloc:
BYTE* temp = realloc(buf,sizeof(BYTE ) * (bufSize+2));
if (temp != NULL)
{
bufSize += 2;
buf = temp;
}
If it is a local variable allocated on the stack you can calculate it like this:
BYTE array[] = { 10, 20, 30, ... };
size_t lenght = sizeof(array) / sizeof(BYTE);
If you receive a pointer to the beginning of the array or you allocate it dynamically(on the heap), you need to keep the length as well as the pointer.
EDIT: I also advise you use STL vector for such needs because it already implements dynamic array semantics.