I'm new to C++ and would like to ask if the code below is an example of a dangling pointer or a memory leak because it is pointing outside the dynamically allocated array:
int * n = new int[10];
for (int prev = 0; prev < 10; prev++) {
*n = *(n + prev + 1);
}
delete[] n;
n = nullptr;
A dangling pointer is a pointer which points to an address where no object resides. I.e. it points at invalid memory. The word "dangling" usually carries the connotation that it used to point to something valid and that something got destroyed (either because it was explicitly deallocated or because it went out of scope).
A memory leak happens when you lose all track of dynamically allocated piece of memory; that is, when you "forget" last pointer that was pointing to that memory, meaning you can no longer deallocate it. Your code would create a memory leak if you did n = nullptr; before you call delete[] n;.
If I had to describe your case with one of these two terms, it would be "dangling pointer," simply because you're reaching beyond the buffer in the last iteration. However, I wouldn't normally call it a "dangling pointer," because it was never valid in the first place. I would call this a "buffer overrun" or an "out-of-bounds access."
What is the difference between a dangling pointer and memory leak?
You could say a dangling pointer is the opposite of a memory leak.
One is a pointer that doesn't point to valid memory, and one is valid memory that nothing points to.
(But as the other answers point out, your code is neither.)
Let's make some canonical examples first:
Memory Leak
int *x;
x = new int;
x = nullptr;
We have allocated an integer on the heap, and then we lost track of it. We have no ability to call delete on that integer at this point. This is a memory leak.
Dangling Pointer
int *x;
x = new int;
delete x;
x is now a dangling pointer. It points to something that used to be valid memory. If we were to use *x at this point, we would be accessing memory that we shouldn't be. Normally, to solve this, after delete x;, we do x = nullptr;
Your code
Your code has a different issue, which I'm going to reduce your code to so that we can more easily talk about the same thing:
int *x;
x = new int[10];
x[9] = x[10];
I would describe this as neither of the above cases. It's a buffer overrun.
Related
I have conducted a few experiments with a simple c program to estimate the cost of fetching a value from main memory as a result of a cache miss.
My first experiment involves accessing a global variable after invalidating the global variable's corresponding cache line with the help of the clflush instruction. BEGIN, CLOSE and GET_TIME are macros I have defined for timing snippets of code using the number of clock cycles as measurement.
int global_var = 0; // Global variable
int main() {
for(int i = 0; i < rounds + warmup; ++i) {
clflush(&global_var);
BEGIN
int x = global_var;
CLOSE
access_times[i] = GET_TIME;
}
return 0;
}
My experiment shows that it costs around ~200 clock cycles to access "global_var" when it is not located in the CPU cache which corresponds to access times I have heard from other sources. However, some main memory accesses in my experiment takes much longer than 200 clock cycles, between 500-1000 clock cycles, which brings me to my first question.
What are likely reasons why some main memory accesses are much slower than the vast majority?
My second experiment involves accessing the same global variable but instead of flushing the cache line with the help of the clflush instruction, I am flushing the entire CPU cache (L1, L2 and L3) by reading a memory block at least as large as my L3 cache (4MB in my case). The size of the written block is kept in the BLOCK_SIZE constant in the code below.
int global_var = 0; // Global variable
int main() {
char *dummy = malloc(BLOCK_SIZE);
for(int i = 0; i < rounds + warmup; ++i) {
memset_s(dummy, 1, BLOCK_SIZE);
BEGIN
int x = global_var;
CLOSE
access_times[i] = GET_TIME;
}
return 0;
}
The result of this experiment shows that if I write a block which is a bit bigger than the size of my L3 cache, most main memory accesses takes roughly 200 clock cycles. However, as I increase the size of the written block the access times becomes larger. For instance, if I write a block of size L3_SIZE * 2, then the average time to fetch "global_var" from main memory is roughly 500 clock cycles.
My second question is, why are main memory access times becoming larger when I clear my CPU cache by writing larger blocks? The memory/cache hierarchy of my system is: L1 -> L2 -> L3 -> Main memory -> Disk.
Thanks in advance.
I saw in some source code something like this
for(int i = 0; i < NUM; i++){
count[i] = new int;
*count[i] = 0;
}
And was wondering what the point was as opposed to just having:
count[i] = 0;
And was wondering what the point was as opposed to just having count[i] = 0;
Well, initializing a pointer to zero has a different meaning than initializing the pointed value to zero.
Dereferencing a pointer that points to a valid object is OK, and returns the value of the object. Dereferencing a pointer with the value zero (i.e. a null pointer) has undefined behaviour.
You may instead be wondering, why would you want to use an array pointers to dynamically allocated integers, instead of an array of integers. You're right to question it, since it is quite rarely a rational choice. However, this snippet doesn't demonstrate any reason for doing so. If possible, you may find out by asking the person who wrote the code.
I am using primitive array type in xcode. Example:
int matrix [10][10];
I am also using a simple loop to initialise the array
for(int x=0;x<=10;x++)
for(int y=0;y<=1;0y++)
matrix[x][y] = 0;
I initialize sevreal matrices in this manner throughout the code. I noticed at times after the initialization is performed, an array that was prviously initialized or updated now contains garbage. Is there a simpler way to initialize an array of this type. And/Or why does this seem to corrupt other arrays.
Your array has 10 positions in both dimensions, but your loops go up to eleven.
Try
for(int x = 0; x < 10; x++)
for(int y = 0; y < 10; y++)
matrix[x][y] = 0;
Notice the use of the lesser than comparator instead of lesser than or equal to.
I suppose you aren't declaring different variables for different matrices and are by mistake overwriting them.
Try It...
matrix=[[NSArray alloc]init];
int myArray[10][10] = {};
THis will create the array and initialize all occurrences to 0;
The most likely cause of corruption like you're seeing (provided that you haven't made the error that #Renan notes), is that you're expecting a stack pointer to exist outside of its scope. You can't, for instance, return matrix to a caller, since the stack frame it's created on will vanish.
Also, since you're allocating on the stack, you need to be careful of your matrix size. If it gets too large, then you'll get stack corruption. 100 ints is generally fine if you're not recursing deeply, but keep in mind the stack limits:
OS X main thread: 8MB
iOS main thread: 1MB
All secondary threads: 512kB
That's the whole stack (all frames, not just the current frame).
How can we use a contiguous block of memory in such a way that some part of it links with the remaining part? For example if I allocate a contiguous block of bytes using malloc, and now I want to structure it in such a way that the initial part of the block will be structured as pointers which points to remaining part. That means the pointers and the pointing objects should be contiguous...??
The question doesn't make much sense to me. Let's assume you wanted nItems of the size sizeBytes (meaning they are all the same size), you would not need to store the pointers, because you can compute the offsets to the allocated memory whenever you needed it. So you are probably missing some criteria in your question. Here is how you'd do that:
void *block = malloc(nItems * sizeBytes);
Then to reach into the n-thobject, you'd simply do:
void *myMemory = block + n * sizeBytes;
You'd want to possibly do some bounds checking there...
But that's too easy, so I'm guessing you really have structures of different sizes that you want to allocate in a single malloc and get access to. So it's not just a question of figuring out what the address of a "sub block of memory" is, but you'd want to know how to cast it so that you can later make sense of the object (assuming it's a C structure). So I guess I'd have to say I remain confused by the question overall.
You'll probably want / need something like the pointer, the size, and the type of structure each "sub block" of memory is supposed to be. This would then indicate what your header information should probably look like. Roughly, you'd want to compute the storage required for your 'meta data' and then the 'payload data', and malloc those things together.
But it's not a trivial thing to implement, because you have to figure out how you tell your function that allocates / initializes the memory block what the mix of objects is going to be (and the sequence of the layout of each sub-object).
I'm afraid this question is woefully underspecified.
If you want a 2D array of one type of object, you can do it like this:
int entries = xSize * ySize; // create a 2D array of xSize by ySize dimensions
size_t buffSize = entries * objectSize; // objectSize is number of bytes for your object
void *block = malloc(buffSize);
Now to access any entry in your 2D array:
void *thingie = block + y * xSize + x;
Now thingie points to block that corresponds to x, y. If you wanted to, you can also change the layout of your memory object. Above I did row-major. You could do:
void *thing = block + x * ySize + y;
That would be column major. The above can extend to n-dimensions:
int entries = xSize * ySize * zSize; // create a 3D array of xSize, ySize, zSize dimensions
size_t buffSize = entries * objectSize; // objectSize is number of bytes for your object
void *block = malloc(buffSize);
And then:
void *thingie = block + z * ySize * xSize + y * xSize + x;
to get to your record in 3D cube. You can take this to any dimension that you want, of course, you'll blow up your memory sooner than later if you're dealing with large objects in large dimensional spaces.
If I am be adding an unknown number of elements to a List, and that list is only going to be iterated through, would a LinkedList be better than an ArrayList in the particular instance (Using Java, if that has any relevance)
The performance trade-offs between ArrayList and LinkedList have been discussed before, but in short: ArrayList tends to be faster for most real-life usage scenarios. ArrayList will cause less memory fragmentation and will play nicer with the Garbage Collector, it will use up less memory and allow for faster iteration, and it will be faster for insertions that occur at the end of the list.
So, as long as the insertions in the list always occur at the last position, there's no reason to pick LinkedList - ArrayList is the clear winner.
Okay Its been already answered but I will still try to put my point.
ArrayList is faster in iteration than LinkedList. The reason is same because arrayList is backed by an array. Lets try to understand whay array iteration is faster then linkedList.
There are 2 factors that work for it
Array is stored as contiguous memory locations (You can say then
what?)
System cache is much faster then accessing memory
But you can ask how Cache fits here. Well check here, CPU tries to take leverage of caches by storing data in cache. It uses Locality of refrence.Now there are 2 techniques which are
Reference Locality of refrence
Temporal locality
If at one point a particular memory location is referenced, then it is likely that the same location will be referenced again in the
near future. There is a temporal proximity between the adjacent
references to the same memory location. In this case it is common to
make efforts to store a copy of the referenced data in special memory
storage, which can be accessed faster. Temporal locality is a special
case of spatial locality, namely when the prospective location is
identical to the present location.
Spatial locality
If a particular storage location is referenced at a particular time, then it is likely that nearby memory locations will be
referenced in the near future. In this case it is common to attempt to
guess the size and shape of the area around the current reference for
which it is worthwhile to prepare faster access.
So if one array location is accessed at a time it will load the adjacent memory locations in cache too. But wait it will not load all. It depends on CACHE_LINES. Well CACHE_LINES define how much bits can be loaded in cache at a time.
So before diving further lest remind what we know
Array is contiguous memory locations
When one memory location of array is accessed adjacent also loaded in memory
How much array memory locations are loaded in memory is defined by CACHE-LINES capacity
SO whenever CPU tries to access a memory location it check if that memory is already in cache. If its present it match else its cache miss.
So from what we know in case of array there will be less cache_miss as compared to random memory locations as in linked list. So it makes sense
and finally from here Array_data_structure from Wikipedia it says
In an array with element size k and on a machine with a cache line
size of B bytes, iterating through an array of n elements requires the
minimum of ceiling(nk/B) cache misses, because its elements occupy
contiguous memory locations. This is roughly a factor of B/k better
than the number of cache misses needed to access n elements at random
memory locations. As a consequence, sequential iteration over an array
is noticeably faster in practice than iteration over many other data
structures, a property called locality of refrence
I guess that answers your question.
For iterating both will have the same O(n) complexity on iterating, ArrayList will take less memory BTW.
public List<Integer> generateArrayList(int n) {
long start = System.nanoTime();
List<Integer> result = new ArrayList<>();
for (int i = 0; i < n; i++) {
result.add(i);
}
System.out.println("generateArrayList time: " + (System.nanoTime() - start));
return result;
}
public List<Integer> generateLinkedList(int n) {
long start = System.nanoTime();
List<Integer> result = new LinkedList<>();
for (int i = 0; i < n; i++) {
result.add(i);
}
System.out.println("generateLinkedList time: " + (System.nanoTime() - start));
return result;
}
public void iteratorAndRemove(List<Integer> list) {
String type = list instanceof ArrayList ? "ArrayList" : "LinkedList";
long start = System.nanoTime();
Iterator<Integer> ite = list.iterator();
while (ite.hasNext()) {
int getDataToDo = ite.next();
ite.remove();
}
System.out.println("iteratorAndRemove with " + type + " time: " + (System.nanoTime() - start));
}
#org.junit.Test
public void benchMark() {
final int n = 500_000;
List<Integer> arr = generateArrayList(n);
List<Integer> linked = generateLinkedList(n);
iteratorAndRemove(linked);
iteratorAndRemove(arr);
}
Arraylist is useful for get random position value, linkedlist useful for insert, remove operate. Above code will show linkedlist very faster than ArrayList, in remove function linkedlist faster than arraylist 1000 times, OMG!!!
generateArrayList time: 15997000
generateLinkedList time: 15912000
iteratorAndRemove with LinkedList time: 14188500
iteratorAndRemove with ArrayList time: 13558249400