C++ Error on Ms Visual Studio: "Windows Has Triggered a Breakpoint in Javaw.Exe"

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 loop for (int r = mid; r < n; r++) right[r] = entries[r]; accesses the array pointed to by right 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 to malloc() to crash.

  • [major: memory leak] You do not free left, nor right. 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 if i is less than nL, nor of j is less than nR before accessing L[i] or R[j]. Testing if the data member is not NULL 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 same data value. You should use L[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



Leave a reply



Submit