String or file entropy [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I'm trying to write string\file entropy calculator. Here is code I wrote but it doesn't work:
double entropy(char* buf)
{
int* rgi = (int*)_alloca(256);
int* pi = rgi + 256;
double H = 0.0;
double cb = sizeof(buf);
for (int i = sizeof(buf); --i >= 0;)
{
rgi[buf[i]]++;
}
while (--pi >= rgi)
{
if (*pi > 0)
{
H += *pi * log2(*pi / cb);
}
}
return -H / cb;
}
What am I doing wrong?

I think you have 4 problems
1) The allocated memory is never initialized
2) Too little memory is allocated as you only allocate 1 byte for each integer
3) Use of char for buf may be a problem as char may be signed
4) sizeof(buf) gives you the size of a char pointer but not the size of the buffer
Besides that I think you make the code too complicated by iterating backwards.
Try this:
double entropy(unsigned char* buf, size_t bufsize)
{
int* rgi = (int*)_alloca(256 * sizeof *rgi);
memset(rgi, 0, 256 * sizeof *rgi);
double H = 0.0;
double cb = bufsize;
for (size_t i = 0; i < bufsize; ++i)
{
rgi[buf[i]]++;
}
for (int i = 0; i < 256; ++i)
{
if (rgi[i] > 0)
{
H += rgi[i] * log2(rgi[i] / cb);
}
}
return -H / cb;
}

Related

Why is my %d specifier putting the "-" after the number? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed last month.
Improve this question
I am trying to make a C implementation of the printf function. Why does my %d specifier return
+2048 - 0 - 1337-!
instead of
-2048 - 0 - -1337!
when I run
int main() {
int ret_val = my_printf("%d - %d - %d!\n", 2048, 0, -1337);
return ret_val;
}
This is my %d specifier code
{
int value = va_arg(args, int);
char buffer[32];
int index = 0;
if (value < 0)
{ //Repair this
buffer[index++] = '-';
value = -value;
}
if (value == 0)
{
buffer[index++] = '0';
}
else
{
while (value > 0)
{
buffer[index++] = '0' + (value % 10);
value /= 10;
}
}
for (int i = 0; i < index / 2; i++)
{
char temp = buffer[i];
buffer[i] = buffer[index - i - 1];
buffer[index - i - 1] = temp;
}
write(1, buffer, index);
size += index;
break;
}
I have tried switching these 2 lines with each
The reason for the symptoms reported by the OP has been quickly and correctly addressed by #EricPostpischil in the comments section.
The problem with writing code from the wrong perspective is that one winds up writing far too much code. Then, lost in the fog of verbose code, patches and bandages are applied that don't quite fulfil the need.
Simply fill the 32-byte buffer from right to left, prefix the minus sign if necessary, and write the correct number of bytes to the output.
int val = va_arg( args, int );
int absVal = abs(val);
char buf[ 32 ];
int i = sizeof buf;
do buf[--i] = (char)('0' + (absVal%10)); while((absVal/= 10) > 0);
if( val < 0 )
buf[--i] = '-';
write( 1, buf + i, sizeof buf - i );
No muss, no fuss trying to reverse the array... or most of it...

Problem with using uninitialized variables [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 3 years ago.
Improve this question
I have two code snippets. Both give me a warning about using uninitialized variables, however, the former throws a segmentation fault while the latter DOESN'T. Please point out what has caused the difference here.
EDIT: They said it is undefined behaviour. So to be clear, i make a char **eligible_file which is undefined, then how can i get around with this without setting a fixed size for the variable?
the first:
glob_t glob1;
glob("*.log", GLOB_ERR, NULL, &glob1);
char** file_name = glob1.gl_pathv;
int file_num = glob1.gl_pathc;
char** eligible_file;
int j = 0;
if (compare_string(argv[1], "-o")) {
for (int i = 0; i < file_num; i++) {
int rc = file_or(file_name[i], argv, 2, argc);
if (rc == 0) {
eligible_file[j] = file_name[i]; // the fault occurs here
j += 1;
}
}
} else {
for (int i = 0; i < file_num; i++) {
int rc = in_file(file_name[i], argv, 1, argc);
if (rc == 0) {
eligible_file[j] = "xasdax"; // the fault occurs here
j += 1;
}
}
}
the latter:
char** fake;
char* me[] = {"qwedsa", "wqdxs", "qwdsx"};
if (1) {
for (int i = 0; i < 3; i++) {
fake[i] = me[i];
}
} else {
for (int i = 0; i < 3; i++) {
fake[i] = "wqxsaa";
}
}
In both code snippets you write to a pointer without allocating memory for it.
1st snippet:
char** eligible_file;
...
eligible_file[j] = file_name[i]; // the fault occurs here
j += 1;
and
char** eligible_file;
...
eligible_file[j] = "xasdax"; // the fault occurs here
j += 1;
2nd snippet:
char** fake;
fake[i] = me[i];
...
fake[i] = "wqxsaa";
I am almost sure that in all cases, the error appears when the array index becomes greater than 0 - that is when writing in un-allocated memory occurs.
You should allocate memory in either of two ways:
Use proper arrays instead of pointers;
use malloc() or other similar function to allocate (enough) memory.
"undefined behavior" = whatever happens, good or bad, do not ask "why?"

realloc is overwriting data [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I am trying to reallocate a char ptr which possess some data. After reallocating to a size that is larger than current, part of the data is being overwritten.
The relevant part of the code is as follows:
char *convertToBinary(char *src, int *fractionPosition, bool double_precision) {
char *res = (char*)malloc(sizeof(char));
int currentResultPos = 0, precision;
int power = (strlen(src) - ((*fractionPosition) + 1)) * (-1);
float decimalValue_i = convertToInt(src, 10, 0, (*fractionPosition) - 1, 0);
float decimalValue_f = convertToInt(src, 10, (*fractionPosition) + 1,
strlen(src) - 1, power);
precision = determinePrecision(double_precision);
res = fromDecimalToDstinationBase(res, &currentResultPos, 2,
decimalValue_i, &firstBinaryDigit);
res = convertFractionIntoResult(res, currentResultPos, 2,
decimalValue_f, precision);
*fractionPosition = currentResultPos - 1;
return res;
}
char *fromDecimalToDstinationBase(char *res, int *resPos, unsigned int dstB,
int decimalValue, char *firstDigit) {
int valueLength, sum = 0, power = 0;
while (decimalValue != 0) {
sum += (decimalValue % dstB) * pow(10, power++);
decimalValue /= dstB;
}
valueLength = countDecimalDigits(sum);
res = copyIntToStr(res, sum, resPos, valueLength);
return res;
}
char *copyIntToStr(char* res, int sum, int *resPos, int power) {
int remainder;
bool flag = true;
res = (char*)calloc(power + (*resPos) + 1, sizeof(char));
power--;
while (sum != 0) {
if (res[0] == '1' && flag) {
addFractionPoint(res, resPos);
flag = false;
}
remainder = sum % (int)pow(10, power);
res[(*resPos)++] = (sum / pow(10, power--)) + '0';;
sum = remainder;
}
res[*resPos] = '\0';
return res;
}
char *convertFractionIntoResult(char *res, int logicalS, unsigned int dstB,
float decimalValue, unsigned int precision) {
//here, logicalS = 5
int physicalS = logicalS, resRemainderCounter = 0;
float remainder = decimalValue;
// here, res = "1.101"
while (resRemainderCounter != precision) {
if (physicalS == logicalS) {
physicalS *= 2;
res = (char*)realloc(res, physicalS * sizeof(char));
// now, res = "1.1ÍÍÍÍÍÍÍýýýý"
}
I looked all over for an explanation. Does anyone knows why this could happen? what I might've done wrong?
EDIT:
also, I tried to replace physicalS with some random really large number, and it didn't change anything.
It appears you're using Microsoft's compiler and library. In debug mode, the library fills uninitialized portions of memory with various values that are intended to stand out when debugging in order to help you detect bugs.
The Í you see corresponds to 0xCD, which is the value the library uses to mark uninitialized portions of heap memory. The ý corresponds to 0xFD, which the library uses to mark areas beyond the ends of a heap allocation. Wikipedia can tell you a lot about these magic numbers.
So let's look at your code:
// here, res = "1.101"
// ...
physicalS *= 2;
res = (char*)realloc(res, physicalS * sizeof(char));
// now, res = "1.1ÍÍÍÍÍÍÍýýýý"
If it can, realloc should return a buffer of at least the requested size. It may be the original buffer, extended, or it may be a new buffer. If it's a new buffer, and the new buffer is larger than the original, then the contents of the original should be copied to the new one. The debug version of the library will fill the rest of the new buffer with 0xCD.
So this result tells me that when you thought res pointed to "1.101", it actually pointed to an unterminated buffer containing 1.1 that happened to be followed by 01 which may have been the result of a buffer overrun.
You then asked for a larger buffer, and the 1.1 was faithfully copied to the beginning, and the debug library then filled the remainder of the new buffer with 0xCD bytes to indicate that it is uninitialized heap memory.
In this case, I would use a debugger to watch the actual buffer sizes at each malloc and realloc and check if the code is actually overwriting the end of the buffer.
Found the error!
When addFractionPoint(res, resPos) was called, another reallocation has been made, which was smaller then the one that was made before that call.
Thanks everyone for your comments.

C Array being overwritten? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
When I run this program : http://hastebin.com/asorawoluw.m
I get this error in GDB :
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401f91 in resoudre (baie=...) at lineaire.c:291
291 printf("type[%d] : %d\n", i, helper_glpk.col_bounds[i]->type);
When i ask gdb to print iI get :
$1 = 1
So the first iteration is failing, but I'm sure I did write into the first case of helper_glpk.col_bounds at the line 200-204 and I did malloc so there's no way (I think ?) that my data is being overwritten or deleted.. so I don't understand why I get this error.
Edit : here's the minimal code :
My structs :
typedef struct Bounds Bounds;
struct Bounds
{
int type;
double lb;
double ub;
};
typedef struct HelperGlpk HelperGlpk;
struct HelperGlpk
{
double *matrix_coefs;
double *obj_coefs;
Bounds **row_bounds;
Bounds **col_bounds;
int *column_of_coef;
int *row_of_coef;
int cpt_coef;
int cpt_contrainte;
};
My functions to generates constraint :
void genere_contrainte_1(int i, int j, HelperGlpk *helper_glpk, Baie baie){
helper_glpk->col_bounds[index_ouverture_serveur(i)]->type = GLP_DB;
helper_glpk->col_bounds[index_ouverture_serveur(i)]->lb = 0;
helper_glpk->col_bounds[index_ouverture_serveur(i)]->ub = 1;
helper_glpk->cpt_coef++;
helper_glpk->col_bounds[index_connexion(i, j, baie.nbr_serveur)]->type = GLP_LO;
helper_glpk->col_bounds[index_connexion(i, j, baie.nbr_serveur)]->lb = 0;
helper_glpk->col_bounds[index_connexion(i, j, baie.nbr_serveur)]->ub = 0;
helper_glpk->cpt_coef++;
}
and the main program is :
void resoudre(Baie baie){
glp_prob *lp;
const int nbr_rows = baie.nbr_client + baie.nbr_serveur * baie.nbr_client; // nombre de contrainte
const int nbr_colums = baie.nbr_serveur + baie.nbr_serveur * baie.nbr_client; // nombre de variable
const int nbr_coefs = 3 * baie.nbr_serveur * baie.nbr_client;
int i, j;
HelperGlpk helper_glpk;
helper_glpk.matrix_coefs = malloc((nbr_coefs + 1) * sizeof(double));
helper_glpk.matrix_coefs[0] = 0;
helper_glpk.obj_coefs = malloc((nbr_colums + 1) * sizeof(double));
helper_glpk.obj_coefs[0] = 0;
helper_glpk.column_of_coef = malloc((nbr_colums + 1) * sizeof(int));
helper_glpk.column_of_coef[0] = 0;
helper_glpk.row_of_coef = malloc((nbr_rows + 1) * sizeof(int));
helper_glpk.row_of_coef[0] = 0;
helper_glpk.col_bounds = malloc((nbr_colums + 1) * sizeof(Bounds *));
for (int index = 0; index <= nbr_colums; index++)
{
helper_glpk.col_bounds[index] = malloc(sizeof(Bounds));
}
helper_glpk.row_bounds = malloc((nbr_rows + 1) * sizeof(Bounds *));
for (int index = 0; index <= nbr_rows; index++)
{
helper_glpk.row_bounds[index] = malloc(sizeof(Bounds));
}
helper_glpk.cpt_coef = 1;
for(i = 1; i <= baie.nbr_serveur; i++)
for(j = 1; j <= baie.nbr_client; j++)
genere_contrainte_1(i, j, &helper_glpk, baie);
for(i = 1; i <= nbr_colums; i++)
printf("type[%d] : %d\n", i, helper_glpk.col_bounds[i]->type);
for(j = 1; j <= baie.nbr_client; j++)
genere_contrainte_2(j, &helper_glpk, baie.nbr_serveur);
The error I get is while I try to printf after the call to generate_contrainte_1
This code is wrong:
helper_glpk.col_bounds = malloc((nbr_colums + 1) * sizeof(Bounds));
You need to fix it with (provided you need nbr_colums + 1 elements):
helper_glpk.col_bounds = malloc((nbr_colums + 1) * sizeof(Bounds *));
for (int index = 0; index < nbr_colums + 1; index++)
{
helper_glpk.col_bounds[index] = malloc(sizeof(Bounds));
}
I have not checked the rest of the code, there could be other errors.
Edit: maybe you don't need the for loop depending on what your genere_contrainte_1 does, but you need to correct your malloc with the right sizeof.
Edit2: I read your genere_contrainte_1, you definitely need all these mallocs. But I really doubt you need row_bounds and col_bounds to be Bounds **, it seems to me Bounds * would have been fine, and that way a single malloc for each field would be enough.

free(ptr) crashes sometimes, pointer is always valid [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am trying to create some streams of bytes, dynamically allocated, and perform a copy of them in some other place. My code is this (earlier i didn`t type from a pc :) ):
void construct_cypherstreams(uint8_t * stream, int key_length, int stream_length, uint8_t ** encr_streams, int * bytes_in_stream) {
// chyperstream = the stream formed of every ith byte
uint8_t * cypherstream;
int length;
length = stream_length / key_length + 1;
// each byte of the key can have values
// between 0 and 256
int i = 0;
int num_added = 0;
for (int k = 0; k < key_length; k++) {
printf("\n%s %d\n", "iteration", k);
i = k; num_added = 0;
cypherstream = (uint8_t *)malloc(length * sizeof (char));
if (cypherstream == NULL) {
printf("%s\n", "could not allocate");
exit(1);
}
else {
printf("%s\n", "succesfully allocated");
}
while (i < stream_length) {
// construct cypherstream
cypherstream[num_added] = stream[i];
num_added++;
i += key_length;
}
printf("\n%s\n", "created cypherstream:");
for (int m = 0; m < num_added; m++) {
printf("%X", cypherstream[m]);
}
printf("\n");
printf("%s\n", "making deep copy...");
encr_streams[k] = (uint8_t *)malloc(num_added * sizeof(char));
// perform deep copy of characters
for (int n = 0; n < num_added; n++) {
encr_streams[k][n] = cypherstream[n];
}
printf("%s\n", "done making deep copy");
free(cypherstream);
printf("%s\n", "succesfully freed");
printf("%s %d\n", "position:", k);
printf("%s %d\n", "num_added:", num_added);
bytes_in_stream[k] = num_added;
printf("%s\n", "iteration ended");
}
}
And I call it like this:
uint8_t ** encr_streams;
int * bytes_in_stream;
encr_streams = (uint8_t **)malloc(key_length * sizeof **encr_streams);
bytes_in_stream = (int *)malloc(key_length * sizeof *bytes_in_stream);
construct_cypherstreams(stream, key_length, stream_length, encr_streams, bytes_in_stream);
Now my program sometimes runs, sometimes crashes.
I am stuck here for the moment and I could really use some help.
Compiler: msvc
Thanks
encr_streams = (uint8_t **)malloc(key_length * sizeof **encr_streams);
just looks wrong. I think it should be
encr_streams = malloc(key_length * sizeof *encr_streams);
because you seem to intend to allocate an array of pointers to uint8_t. Then you probably also have to initialize the elements of that array by something.
This is a case of heap corruption as you are trying to overwrite some dynamically allocated memory.
If you program on Linux, run your code under the valgrind memory debugger:
http://valgrind.org/docs/manual/quick-start.html
For Windows... you may want to try MS AppVerifier though I haven't used it for years and forgot almost everything about it :-(
How to use Microsoft Application Verifier

Resources