Windows has triggered a breakpoint in myprogram.exe
A star is missing within sizeof:
memset(a,0,a_size*sizeof(*a));
That's because:
sizeof(a) == sizeof(int*) -- usually 4 or 8
sizeof(*a) == sizeof(int) -- usually 4
Windows has triggered a breakpoint due to corruption in heap or dlls loaded
What would happen if you changed your external declaration from
[DllImport("QuerySegmentation.dll", EntryPoint = "fnsegcExported", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern StringBuilder fnsegcExported();
to
[DllImport("QuerySegmentation.dll", EntryPoint = "fnsegcExported", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern string fnsegcExported();
And then called it in the following way:
this.stringbuildervar = new StringBuilder(fnsegcExported());
string
seems the more appropriate type. Or better yet use the Marshal
class to marshal your unmanaged char* return into a managed string.
[DllImport("QuerySegmentation.dll", EntryPoint = "fnsegcExported", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern IntPtr fnsegcExported();
string managedStr = Marshal.PtrToStringAnsi(fnsegcExported);
this.stringbuildervar = new StringBuilder(managedStr);
Windows has triggered a breakpoint
If that is the full definition of IPrintable
the problem is that m_pStr
is unitialised meaning there will be an incorrect invocation of delete[]
.
This fails:
v1 = Vector();
because a temporary Vector
is created and the faulty destructor is executed immediately. To correct initialise m_pStr
or a better solution would be to use std::string
. If you must use a char*
then you must also implement a copy constructor and assignment operator or prevent copying (see What is The Rule of Three?).
Critical error detected c0000374. MergeSort.exe has triggered a breakpoint
There are multiple problems in the code causing undefined behavior:
[major: undefined behavior] In the
merge_sort
function, the loopfor (int r = mid; r < n; r++) right[r] = entries[r];
accesses the array pointed to byright
beyond the end. You should write:for (int r = mid; r < n; r++)
right[r - mid] = entries[r];This bug is a good candidate to explain the observed behavior as it corrupts the
malloc()
internal data, causing a subsequent call tomalloc()
to crash.[major: memory leak] You do not free
left
, norright
. As a matter of fact, allocating copies of the left and right parts of the array is not even necessary.[major: undefined behavior] In the
merge
function, you do not test ifi
is less thannL
, nor ofj
is less thannR
before accessingL[i]
orR[j]
. Testing if thedata
member is notNULL
does not suffice, accessing an element beyond the end of an array has undefined behavior.[minor: unstable sort]
L[i].data < R[i].data
might not preserve the order of entries that have the samedata
value. You should useL[i].data <= R[i].data
to implement stable sorting.[hint] Defining
typedef char *String;
is a bad idea. Do not hide pointers behind typedefs, it is confusing and error prone.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct EntryStruct {
int data;
char *name;
} Entry;
#ifdef _MSC_VER
// define strdup on legacy systems
char *strdup(const char *s) {
size_t len = strlen(s);
char *p = (char *)malloc(len + 1);
if (p)
memcpy(p, s, len + 1);
return p;
}
#endif
void merge(Entry *output, Entry *L, int nL, Entry *R, int nR) {
int i = 0;
int j = 0;
int k = 0;
while (k < nL + nR) {
if (i < nL && (j >= nR || L[i].data <= R[j].data)) {
output[k] = L[i];
i++;
} else {
output[k] = R[j];
j++;
}
k++;
}
}
void merge_sort(Entry *entries, int n) {
if (n > 1) {
int mid = n / 2;
Entry *temp;
Entry *left = entries;
Entry *right = entries + mid;
merge_sort(left, mid);
merge_sort(right, n - mid);
temp = (Entry *)malloc(n * sizeof(Entry));
merge(temp, left, mid, right, n - mid);
for (int i = 0; i < n; i++) {
entries[i] = temp[i];
}
free(temp);
}
}
Entry Entry_create(int data, const char *name) {
Entry node;
node.name = strdup(name);
node.data = data;
return node;
}
void printArrByName(Entry *arr, int n) {
for (int i = 0; i < n; i++) {
printf("%s\n", arr[i].name);
}
}
int main(void) {
Entry *arr = malloc(5 * sizeof(*arr));
arr[0] = Entry_create(5, "abc");
arr[1] = Entry_create(6, "def");
arr[2] = Entry_create(2, "ghijk");
arr[3] = Entry_create(3, "ksdljf");
arr[4] = Entry_create(1, "lsdfjl");
merge_sort(arr, 5);
printArrByName(arr, 5);
for (int i = 0; i < 5; i++)
free(arr[i].name);
free(arr);
return 0;
}
C++, function that checks if software runs on 32-bit or 64-bit system
Rather than writing two size-dependent branches, just write one correct, portable code path. In your case:
(int**)malloc(count*sizeof(int*));
This will work correctly regardless of the sizeof of int*
on your system.
Postscript: As you can see from this literal answer to your question, you are better off not having an if:
if(sizeof(int*) == sizeof(int))
x = (int**)malloc(count*sizeof(int));
else if (sizeof(int*) == sizeof(int64_t))
x = (int**)malloc(count*sizeof(int64_t));
Hopefully you can see how absurdly redundant that code is, and how it should be replaced by a single well-constructed malloc
call.
Related Topics
Template Metaprogramming: (Trait For) Dissecting a Specified Template into Types T<T2,T3 N,T4, ...>
How Is Push_Back Implemented in Stl Vector
Register an Object Creator in Object Factory
0Xc0000005: Access Violation Reading Location 0X00000000
Why Are Override and Final Identifiers with Special Meaning Instead of Reserved Keywords
C++ Is It Necessary to Delete Dynamically Allocated Objects at the End of the Main Scope
When Did "And" Become an Operator in C++
What Is a Cross-Platform Way to Get the Current Directory
Why Default Return Value of Main Is 0 and Not Exit_Success
How to Read System Information in C++
What Happens to an Stl Iterator After Erasing It in VS, Unix/Linux
Why How to Implicitly Convert an Int Literal to an Int * in C But Not in C++
All K Nearest Neighbors in 2D, C++
Neatest Way to Loop Over a Range of Integers
What Is Double Evaluation and Why Should It Be Avoided