Trace/breakpoint trap during reallocation - c

I have a graph code written a year ago which does not work now (AFAIR it worked). The graph is implemented with a square matrix which is symmetric respectively to the diagonal. I have omitted a lot of code to keep it as clear as possible, and this is still enough for the error to persist.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct
{
int **matrix;
unsigned size;
} graph;
void init(graph *gptr, int *matrix[], unsigned size)
{
gptr->size = size;
gptr->matrix = malloc(gptr->size * sizeof(*gptr->matrix));
for (unsigned i = 0; i < gptr->size; i++)
gptr->matrix[i] = malloc(gptr->size * sizeof(**gptr->matrix));
for (unsigned i = 0; i < gptr->size; i++)
for (unsigned j = 0; j <= i; j++)
gptr->matrix[i][j] = gptr->matrix[j][i] = matrix[i][j];
}
void add_vertex(graph *gptr, unsigned vertex)
{
for (unsigned i = 1; i < gptr->size; i++)
if (gptr->matrix[i][0] == vertex) return;
gptr->size++;
gptr->matrix = realloc(gptr->matrix, gptr->size * sizeof(*gptr->matrix));
for (unsigned i = 0; i < gptr->size; i++)
/* ERROR */
gptr->matrix[i] = realloc(gptr->matrix[i], gptr->size * sizeof(**gptr->matrix));
gptr->matrix[gptr->size - 1][0] = gptr->matrix[0][gptr->size - 1] = vertex;
for (unsigned i = 1; i < gptr->size; i++)
gptr->matrix[gptr->size - 1][i] = gptr->matrix[i][gptr->size - 1] = -1;
}
#define EDGES 7
#define RANDOM(min, max) min + rand() / ((RAND_MAX - 1) / (max - min))
#define MIN -1
#define MAX 9
int **getMatrix(unsigned size)
{
int **matrix = malloc(size * sizeof(*matrix));
for (unsigned i = 0; i < size; i++)
{
matrix[i] = malloc((i + 1) * sizeof(**matrix));
matrix[i][0] = i;
}
for (unsigned i = 1; i < size; i++)
{
for (unsigned j = 1; j < i; j++)
do
matrix[i][j] = RANDOM(MIN, MAX);
while (!matrix[i][j]);
matrix[i][i] = rand() % 2 - 1;
}
return matrix;
}
int main(void)
{
int **matrix = getMatrix(EDGES + 1);
graph x;
init(&x, matrix, EDGES + 1);
add_vertex(&x, EDGES + 1);
}
At gptr->matrix[i] = realloc(gptr->matrix[i], gptr->size * sizeof(**gptr->matrix)); the program gets paused by an exception Trace/breakpoint trap. I have googled for a while, and to me it's most likely there is something wrong with my reallocation, but I have no idea what's wrong. Besides, it works fine on clang and even on online gcc 7.4 whereas fails to succeed on my gcc 8.1. Can anyone see where I'm mistaken?

On the first entry to add_vertex, gptr->size == 8 and gptr->matrix points to an array of 8 pointers to malloc'ed memory.
gptr->size++;
Now gptr->size == 9.
gptr->matrix = realloc(gptr->matrix, gptr->size * sizeof(*gptr->matrix));
And now gptr->matrix points to an array of 9 pointers. gptr->matrix[0] .. gptr->matrix[7] are the valid malloc'ed pointers from before, and gptr->matrix[8] contains uninitialized garbage.
for (unsigned i = 0; i < gptr->size; i++)
/* ERROR */
gptr->matrix[i] = realloc(gptr->matrix[i], gptr->size * sizeof(**gptr->matrix));
Since gptr->size == 9, this iterates 9 times, and on the 9th iteration, the garbage pointer gptr->matrix[8] is passed to realloc. Not good.
You could iterate the loop gptr->size - 1 times instead, and initialize gptr->matrix[gptr->size - 1] = malloc(...) separately. Or to be a little lazy and avoid code duplication, you could initialize gptr->matrix[gptr->size - 1] = NULL before this loop, keep it iterating gptr->size times, and rely on the handy feature that realloc(NULL, sz) is equivalent to malloc(sz).

Related

As a result of processing arrays -nan(ind)

I am writing a program that creates arrays of a given length and manipulates them. You cannot use other libraries.
First, an array M1 of length N is formed, after which an array M2 of length N is formed/2.
In the M1 array, the division by Pi operation is applied to each element, followed by elevation to the third power.
Then, in the M2 array, each element is alternately added to the previous one, and the tangent modulus operation is applied to the result of addition.
After that, exponentiation is applied to all elements of the M1 and M2 array with the same indexes and the resulting array is sorted by dwarf sorting.
And at the end, the sum of the sines of the elements of the M2 array is calculated, which, when divided by the minimum non-zero element of the M2 array, give an even number.
The problem is that the result X gives is -nan(ind). I can't figure out exactly where the error is.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
const int A = 441;
const double PI = 3.1415926535897931159979635;
inline void dwarf_sort(double* array, int size) {
size_t i = 1;
while (i < size) {
if (i == 0) {
i = 1;
}
if (array[i - 1] <= array[i]) {
++i;
}
else
{
long tmp = array[i];
array[i] = array[i - 1];
array[i - 1] = tmp;
--i;
}
}
}
inline double reduce(double* array, int size) {
size_t i;
double min = RAND_MAX, sum = 0;
for (i = 0; i < size; ++i) {
if (array[i] < min && array[i] != 0) {
min = array[i];
}
}
for (i = 0; i < size; ++i) {
if ((int)(array[i] / min) % 2 == 0) {
sum += sin(array[i]);
}
}
return sum;
}
int main(int argc, char* argv[])
{
int i, N, j;
double* M1 = NULL, * M2 = NULL, * M2_copy = NULL;
double X;
unsigned int seed = 0;
N = atoi(argv[1]); /* N равен первому параметру командной строки */
M1 = malloc(N * sizeof(double));
M2 = malloc(N / 2 * sizeof(double));
M2_copy = malloc(N / 2 * sizeof(double));
for (i = 0; i < 100; i++)
{
seed = i;
srand(i);
/*generate*/
for (j = 0; j < N; ++j) {
M1[j] = (rand_r(&seed) % A) + 1;
}
for (j = 0; j < N / 2; ++j) {
M2[j] = (rand_r(&seed) % (10 * A)) + 1;
}
/*map*/
for (j = 0; j < N; ++j)
{
M1[j] = pow(M1[j] / PI, 3);
}
for (j = 0; j < N / 2; ++j) {
M2_copy[j] = M2[j];
}
M2[0] = fabs(tan(M2_copy[0]));
for (j = 0; j < N / 2; ++j) {
M2[j] = fabs(tan(M2[j] + M2_copy[j]));
}
/*merge*/
for (j = 0; j < N / 2; ++j) {
M2[j] = pow(M1[j], M2[j]);
}
/*sort*/
dwarf_sort(M2, N / 2);
/*sort*/
X = reduce(M2, N / 2);
}
printf("\nN=%d.\n", N);
printf("X=%f\n", X);
return 0;
}
Knowledgeable people, does anyone see where my mistake is? I think I'm putting the wrong data types to the variables, but I still can't solve the problem.
Replace the /* merge */ part with this:
/*merge*/
for (j = 0; j < N / 2; ++j) {
printf("%f %f ", M1[j], M2[j]);
M2[j] = pow(M1[j], M2[j]);
printf("%f\n", M2[j]);
}
This will print the values and the results of the pow operation. You'll see that some of these values are huge resulting in an capacity overflow of double.
Something like pow(593419.97, 31.80) will not end well.

Dynamic Memory in C [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I can't understand what doing the row
*(m[i] + sizes[i] - 1) = n;
#include <stdio.h>
#include <stdlib.h>
#define MAXSTR 100
int main()
{
int i, j, k, n;
char str[MAXSTR];
printf("Enter amount of rows: ");
fgets(str, MAXSTR, stdin);
k = atoi(str);
int* sizes = (int * ) calloc(k, sizeof(int));
int* sum = (int * ) calloc(k, sizeof(int));
int** m = (int ** ) calloc(k, sizeof(int * ));
printf("Enter matrix:\n");
for (i = 0; i < k; i++)
{
fgets(str, MAXSTR, stdin);
char* sym = str;
while (1)
{
m[i] = (int * ) realloc(m[i], (++sizes[i]) * sizeof(int));
n = strtol(sym, & sym, 10);
sum[i] += n;
if (n)
{
*(m[i] + sizes[i] - 1) = n;
}
else
{
--sizes[i];
break;
}
}
}
printf("\nMatrix: \n");
for (i = 0; i < k; i++)
{
for (j = 0; j < sizes[i]; j++)
printf("%i ", *(m[i] + j));
printf("\n");
}
printf("\nSum of elements of row:\n");
for (i = 0; i < k; i++)
printf("#%i - %i\n", i + 1, sum[i]);
free(sizes);
free(sum);
free(m);
return 0;
m is the matrix. Or more formally, it appears to be an array of "rows". Where each row is an array of integers.
sizes[i] is the length of the row represented by m[i].
This expression
*(m[i] + sizes[i] - 1) = n;
Appears to assign the value n to the last index of the row identified by m[i]. Essentially, it's appending to the end of the reallocated array.
This entire block of code is a bit complex:
while (1)
{
m[i] = (int * ) realloc(m[i], (++sizes[i]) * sizeof(int));
n = strtol(sym, & sym, 10);
sum[i] += n;
if (n)
{
*(m[i] + sizes[i] - 1) = n;
}
else
{
--sizes[i];
break;
}
}
It could be simplified to just:
int rowsize = 0;
while (1)
{
n = strtol(sym, &sym, 10); // parse the next number in str
if (n == 0) // the row ends when 0 is read
{
break;
}
m[i] = (int *)realloc(m[i], (rowsize+1) * sizeof(int); // grow the row's size by 1
m[i][rowsize] = n;
sum[i] += n;
rowsize++;
}
sizes[i] = rowsize;
m[i] is a pointer to the first element in the i:th matrix row
sizes[i] is the current number of columns in row i
sizes[i] - 1 is the last element in row i
m[i] + sizes[i] - 1 is a pointer to the last element in row i
*(m[i] + sizes[i] - 1) is the last element in row i
When allocating memory in C the result should not be cast, so
int* sizes = (int * ) calloc(k, sizeof(int));
should be simply
int* sizes = calloc(k, sizeof(int));
Also, the rows of the matrix m are never freed; to free the entire matrix you would need
for (i = 0; i < k; i++) {
free(m[i]);
}
free(m);
To answer your question the statement *(m[i] + sizes[i] - 1) = n; assigns the value n to whatever m[i] + sizes[i] - 1 points to. m is a pointer to a pointer to an int, so m[i] is an address of an int pointer. sizes[i] - 1 is usually how you convert from a size to index, so it's an offset from that int pointer.
Here are some suggested changes (all but one implemented below):
Reduce variable scope but initialize sum to NULL before the first failure so it can be unconditionally deallocated
It is better user experience to just read the data and terminate with an empty line instead of asking for the user count upfront. Just update the count k as we go along. This eliminates atoi which does not do any error handling. If you want to crash the program due to being out of memory you have to provide the data not just large a count.
(not fixed) realloc of 1 element at a time, if the O(i^2) is a performance issue, keep track of size and capacity of sum. When size == capacity, realloc by some factor, say, 2. Optionally, realloc to size when when we finish reading data as we now have the actual number of lines k.
No point of printing the array you just entered, which means we can get rid of the m and sizes arrays
Deallocate sum if realloc fails by introducing a temporary sum2 variable that will be NULL on error, but sum will still point to previously allocated data
Check for under and overflow of n and sum
Use sizeof on variable instead of type so you can change type just one place if needed
Allow 0 values by passing in by using a separate pointer endptr than sym to strtol()
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#define CHECK(p, msg) if(!(p)) {\
printf("%s:%d %s\n", __FILE__, __LINE__, (msg));\
goto out;\
}
#define MAXSTR 100
int main() {
int k;
char str[MAXSTR];
int *sum = NULL;
printf("Enter matrix:\n");
for(int i = 0;; i++) {
fgets(str, MAXSTR, stdin);
char *sym = str;
int *sum2 = realloc(sum, (i + 1) * sizeof(*sum));
CHECK(sum2, "realloc failed");
sum = sum2;
int j;
for(j = 0;; j++) {
char *endptr;
long n = strtol(sym, &endptr, 10);
CHECK(n >= INT_MIN && n <= INT_MAX,\
"value truncated");
if(sym == endptr) {
break;
}
sym = endptr;
CHECK((n >= 0 && sum[i] <= INT_MAX - n) || \
(n < 0 && sum[i] >= INT_MIN - n),\
"sum truncated");
sum[i] += n;
}
if(!j) {
k = i;
break;
}
}
printf("Sum of elements of row:\n");
for (int i = 0; i < k; i++)
printf("#%i - %i\n", i + 1, sum[i]);
out:
free(sum);
return 0;
}
Example execution:
Enter matrix:
0 1 2
Sum of elements of row:
#1 - 3

Can't figure out what's wrong with my code for a HackerRank problem in C

I'm sorry to ask help for a HackerRank problem here, I know it's not really the right place but nobody is answering me on HackerRank. Also, I'm new in C, so don't be to rude please.
Problem's description:
You are given n triangles, specifically, their sides a, b and c. Print them in the same style but sorted by their areas from the smallest one to the largest one. It is guaranteed that all the areas are different.
Link to the problem : https://www.hackerrank.com/challenges/small-triangles-large-triangles/problem
We can only edit the sort_by_area function.
First of all, I didn't calculate the triangles' area, I've just calculated the perimeter of each triangle, because the formula is simpler to read and to execute. Normally, that doesn't change anything for the result since a bigger perimeter means a bigger area. Tell me if I'm wrong.
The problem is that I have unexpected results: there's numbers on a line from my output that I really don't know from where they come. See:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct {
int a;
int b;
int c;
} triangle;
void sort_by_area(triangle *tr, int n) {
// Array for storing the perimeter.
int *size = malloc(100 * sizeof(*size));
// Adding perimeters in size array.
for (int i = 0; i < n; i++) {
size[i] = tr[i].a + tr[i].b + tr[i].c;
}
// Sort.
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (size[j] > size[j + 1]) {
// Sort in size array.
int temp = size[j];
size[j] = size[j + 1];
size[j + 1] = temp;
// Sort in tr array.
temp = tr[j].a;
tr[j].a = tr[j + 1].a;
tr[j + 1].a = temp;
temp = tr[j].b;
tr[j].b = tr[j + 1].b;
tr[j + 1].b = temp;
temp = tr[j].c;
tr[j].c = tr[j + 1].c;
tr[j + 1].c = temp;
}
}
}
}
int main() {
int n;
scanf("%d", &n);
triangle *tr = malloc(n * sizeof(triangle));
for (int i = 0; i < n; i++) {
scanf("%d%d%d", &tr[i].a, &tr[i].b, &tr[i].c);
}
sort_by_area(tr, n);
for (int i = 0; i < n; i++) {
printf("%d %d %d\n", tr[i].a, tr[i].b, tr[i].c);
}
return 0;
}
Input:
3
7 24 25
5 12 13
3 4 5
Output:
0 417 0 // Unexpected results on this line.
3 4 5
5 12 13
Expected output:
3 4 5
5 12 13
7 24 25
It seems that an error occurs from the 7 24 25 triangle, but for me, my code seems to be good.... Can you help to find out what's wrong ? I really want to understand before going to another problem.
The assumption that a greater parameter implies a greater area is incorrect. Why? Imagine an isosceles triangle with a base of 1000 units and a height of 1e-9 units. The area is minuscule, compared to an equilateral triangle with unit length whereas the former has a huge perimeter (~2000 units) compared to the latter (3 units). That's just an (extreme) example to convey the flaw in your assumption.
I'd suggest you roll up your own area function. It's even mentioned on the problem page to use Heron's formula. Since it's just to be used in the comparison, then we don't need the exact area but an indicative area. So something like
double area(triangle const* tr) {
if(tr) {
double semiPerimeter = (tr->a + tr->b + tr->c)/2.0;
return semiPerimeter* (semiPerimeter - tr->a) * (semiPerimeter - tr->b) * (semiPerimeter - tr->c);
} else {
return 0;
}
}
Where we don't really need to calculate the square root since we just need to compare the areas across triangles and comparing the square of areas across triangles should be fine.
After this, it's just a matter of plugging this into whatever you did, after correcting the inner j loop to run only till n-1 (as the other answer has also explained)
void sort_by_area(triangle* tr, int n) {
/**
* Sort an array a of the length n
*/
double areaArr[n];
for(size_t i = 0; i < n; ++i) {
areaArr[i] = area(&tr[i]);
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n - 1; j++) {
if (areaArr[j] > areaArr[j + 1]) {
// Sort in area array.
int temp = areaArr[j];
areaArr[j] = areaArr[j + 1];
areaArr[j + 1] = temp;
// Sort in tr array.
triangle tmp = tr[j];
tr[j] = tr[j + 1];
tr[j + 1] = tmp;
}
}
}
}
You could directly use qsort too here since the problem doesn't prohibit using standard functions, something like:
int qsortCompare(void const* a, void const* b) {
triangle const* trA = a;
triangle const* trB = b;
if(trA && trB) {
double areaA = area(trA);
double areaB = area(trB);
return (areaA < areaB) ? -1 :
((areaA > areaB)? 1: 0);
}
return 0;
}
void sort_by_area(triangle* tr, int n) {
qsort(tr, n, sizeof(triangle), &qsortCompare);
}
Also, don't be restricted to add functions in the problem solution. The actual driver code only calls sort_by_area() but you can write other functions in the solution and call them from sort_by_area().
The inner loop does not need to run till n, only till n-1
for (int j = 0; j < n - 1; j++)
Because when j == n, then you are comparing with random junk outside of your respective arrays by accessing size[j+1] and tr[j+1].
Also, when swapping, you don't need to copy the structure members one-by-one. You can simply do:
// Sort in tr array.
triangle tmp = tr[j];
tr[j] = tr[j + 1];
tr[j + 1] = tmp;
Edit: As #CiaPan pointed out:
You have a memory leak. You need to call free() after you are done with using the malloc'd memory.
You are not allocating the right amount of memory. If you are passed more than 100 triangles, your code might behave weirdly or randomly crash.
int *size = malloc(n* sizeof(*size));
Full code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct {
int a;
int b;
int c;
} triangle;
void sort_by_area(triangle *tr, int n) {
// Array for storing the perimeter.
int *size = malloc(n* sizeof(*size));
// Adding perimeters in size array.
for (int i = 0; i < n; i++) {
size[i] = tr[i].a + tr[i].b + tr[i].c;
}
// Sort.
for (int i = 0; i < n; i++) {
for (int j = 0; j < n - 1; j++) {
if (size[j] > size[j + 1]) {
// Sort in size array.
int temp = size[j];
size[j] = size[j + 1];
size[j + 1] = temp;
// Sort in tr array.
triangle tmp = tr[j];
tr[j] = tr[j + 1];
tr[j + 1] = tmp;
}
}
}
}
int main() {
int n;
scanf("%d", &n);
triangle *tr = malloc(n * sizeof(triangle));
for (int i = 0; i < n; i++) {
scanf("%d%d%d", &tr[i].a, &tr[i].b, &tr[i].c);
}
sort_by_area(tr, n);
for (int i = 0; i < n; i++) {
printf("%d %d %d\n", tr[i].a, tr[i].b, tr[i].c);
}
return 0;
}

segmentation failure while allocating memory for a 2D array in c

I have a function that returns all the combinations of letters possible in the alphabet with repetition in a word of length LENTH_MAX. The function returns these combinations in a 2D array call 'arr'.
Since calculating the total number of arrays is a pain because you need to calculate factorial numbers [ (n + r - 1)!/r!(n - 1)! ] I decided to increasingly reallocate memory for the arrays in 'arr' as needed.
I set a variable called capacity that determinetes the initial size of 'arr' and a constant called CAP_INCR that specifies the number of arrays for which memory will be reallocated in addition to the memory already assigned. The program compiles ok by if I set CAP_INCR to 1, so that each time a new combination is found new memory is allocated for that array, the program crushes with a Segmentation fault: 11 message, if I set CAP_INCR to 100 if finishes correctly but the output is wrong, the first combination 'a a a' is repeated twice and the last combination 'z z z' is mission.
I'd really appreciate some help. I'm a decent programer in other languages but I'm just starting with C.
The code is:
#include <stdio.h>
#include <stdlib.h>
const unsigned short LENGTH_MAX = 3;
const char alphabet[] = "abcdefghijklmnopqrstuvwxyz";
#define CAP_INCR 1 /* memory increases */
unsigned char* combinations(unsigned char n, unsigned char r)
{
// n length of alphabet
// r length of figures
unsigned int set_counter = 0; //counting generated sequences
unsigned char *vector = NULL; //where the current figure is stored
unsigned char *arrTemp = NULL; // Temporary pointer store
unsigned int capacity = 100; // count current size of arr
unsigned char *arr = (unsigned char *)malloc(capacity * r * sizeof(unsigned char)); // multidimentional array
vector = (unsigned char *)malloc(sizeof(unsigned char) * r);
if(vector == NULL || arr == NULL)
{
fprintf(stderr, "error: insufficient memory\n");
exit(EXIT_FAILURE);
}
//initialize: vector[0, ..., r - 1] are 0, ..., r - 1
for(int l = 0; l < r; l++) //for(int l = 0; l < r; l++) // no repetition
vector[l] = 0;
//generate all successors
while(1)
{
set_counter++;
// check is arr current capacity is enough
if(set_counter > capacity)
{ // We need more memory
capacity += CAP_INCR;
arrTemp = (unsigned char *)realloc(arr, capacity * r * sizeof(unsigned char));
if(!arrTemp)
{
printf("Unfortunately memory reallocation failed.\n");
free(arr);
arr = NULL;
exit(0);
}
arr = arrTemp;
}
for(int x = 0; x < r; x++) { // assign a new combination to arr
//printf("%c ", alphabet[vector[x]]);
*(arr + set_counter*r + x) = vector[x];
}
//printf("(%u)\n", set_counter);
int j; //index
//easy case, increase rightmost element
if(vector[r - 1] < n - 1)
{
vector[r - 1]++;
continue;
}
//find rightmost element to increase
for(j = r - 2; j >= 0; j--) {
if(vector[j] != n - 1) {
break;
}
}
//terminate if vector[0] == n - r
if(j < 0)
break;
//increase
vector[j]++;
//set right-hand elements
for(j += 1; j < r; j++)
vector[j] = vector[j - 1];
}
return arr;
}
int main() {
unsigned char* arr = combinations(sizeof(alphabet)-1, LENGTH_MAX);
int c=0;
for (int i = 0; i < 3276; i++) // 3276 is the total number of combinations
{
for (int j = 0; j < 3; j++)
{
printf("%c ", alphabet[*(arr + i*3 + j)]);
}
printf("count: %d\n",++c);
}
return 0;
}

Stack around the variable 's' was corrupted

I got this error in my rc4 algorithm, it works well, but i got this error every time when the message is too big, like 1000kB, here is the code:
char* rc4(const int* key, int key_size, char* buff, int buff_size){
int i, j, k;
int s[255], rk[255]; //rk = random_key
char* encrypted = alloc_char_buffer(buff_size);
for (i = 0; i < 255; i++){
s[i] = i;
rk[i] = key[i%key_size];
}
j = 0;
for (i = 0; i < 255; i++){
j = (j + s[j] + rk[i]) % 256;
SWITCH(s + i, s + j);
}
i = 0;
j = 0;
for (k = 0; k < buff_size; k++){
i = (i + 1) % 256;
j = (j + s[i]) % 256;
SWITCH(s + i, s + j);
//try{
//}
//catch ()
encrypted[k] = (char)(s[(s[i] + s[j]) % 256] ^ (int)buff[k]);
}
encrypted[buff_size] = 0;
return encrypted;
}
at the end o the last loop i got this error, i think this is some type of buffer overflow error, the only variable able to do that is the 'encrypted' but at the end of the loop, the value of the variable 'k' have the exactly same value of 'buff_size' that is used to alloc memory for 'encrypted', if someone can help i'll thank you
the 'encrypted' is "non-null terminated", so if the string have 10 bytes i will allocate only 10 bytes, not 11 for the '\0'
if you need, here is the code for alloc_char_buffer(unsigned int)
char* alloc_char_buffer(unsigned int size){
char* buff = NULL;
buff = (char*)calloc(size+1, sizeof(char));
if (!buff)
_error("program fail to alloc memory.");
return buff;
}
SWITCH:
//inversão de valores
void SWITCH(int *a, int *b){
*(a) = *(a) ^ *(b); //a random number
*(b) = *(a) ^ *(b); //get a
*(a) = *(a) ^ *(b); //get b
}
char* encrypted = alloc_char_buffer(buff_size);
/* ... */
encrypted[buff_size] = 10;
Here is the problem. You allocate buff_size elements. Thus, the last valid index is buff_size-1, not buff_size.
Another issue:
j = (j + s[j] + rk[i]) % 256;
Thus the range of j is [0, 255], but the legal index of s is only [0, 254]. You should either declare s as a 256-element array or review the algorithm implementation.
Your following line is creating the problem as you are trying to access beyond your allocated memory.
encrypted[buff_size] = 10;
Additionally, you should avoid use calloc instead of writing your own function alloc_char_buffer. It would allocate memory and initialize with 0.
calloc(buff_size, sizeof(char));

Resources