C arrays calling functions - c

below is my code for your reference. Rx_Buf contains one of the two values from Rfid_Tag[][]. I am getting tht value from another function and I want to find and confirm. the problem is its not working. Rfid_Tag[][] has different values i.e. its corrupted. I am not sure how a global variable defined is getting corrupted. I tried declaring it const, extern still the same problem.When i run this as standalone program it works perfectly, but when I call this function from main.c its not working. Can anyone pleasee help me with this.
Thanks
#define NUMBER_OF_RFID_TAGS 2
#define RFID_DATA_LENGTH 17
unsigned char Rfid_Tag[NUMBER_OF_RFID_TAGS][RFID_DATA_LENGTH]= {
{0x96,0x12,0xf1,0x6e,0xda,0x57,0x98,0x02,0x00,0xe1,0x50,0x00,0x00,0x00,0x00,0x00,0x11},
{0x96,0x72,0xe9,0x6e,0xda,0x2f,0x98,0x02,0x00,0xe1,0x50,0x00,0x00,0x00,0x00,0x00,0x11}
};
int RFID_check(char *Rx_Buf)
{
//unsigned char ucRfidReceivedData[RFID_DATA_LENGTH]= *Rx_Buf; //{0x00,0x01,0x2,0x03,0x04,0x5,0x06,0x07,0x8,0x09,0x0A,0xB,0x0C,0x0D,0xE,0x0F,0x10};
unsigned count = 0;
int found = false;
for(int i = 0; i < NUMBER_OF_RFID_TAGS; i++){
count = 0;
for(int j = 0; j < RFID_DATA_LENGTH; j++){
if(Rfid_Tag[i][j] == Rx_Buf[j]){
count++;
//PORTR.DIR = 0xff;
//PORTR.OUTTGL = 0xff;
}
}
if(count == RFID_DATA_LENGTH){
found = true;
break;
}
}
if(found == true){
PORTR.DIR = 0xff;
PORTR.OUTTGL = 0x0f;
RFID_accept();
}
else{
RFID_error();
PORTR.DIR = 0xff;
PORTR.OUTTGL = 0x00;
}
return 0;
}

Related

Tools to expand or inline sub-functions in C-code

Background:
Often I have to deal with C source code without any documentation during firmware development/maintenance. When the code deals with big data structures where the data members initialization scattered all over the place, it becomes very challenging to jump around different source and header files and often I got lost.
So my current solution is to spend several days to "flatten out" the code. I don't know what the appropriate term, but basically what I do is expanding the sub-functions and replacing the input parameters variable names with the actual variable names that passed into the sub-function. (Please see an oversimplified example below)
The outcome of this exercise is very helpful, but it is a very manual and tedious process. Since I'm doing firmware, on some chips that supports trace capability, it is possible to do this using JTAG debugger. But this set up is not always available.
I know with macros I can use the preprocessor to do this, but I couldn't figure out how to do it with sub-functions, if such a tool exists. I tried Googling 'subfunction expansion' etc., so far no luck. Please let me know if you know such a tool exists or the proper term(s) of what I'm trying to do so I can search it better on the Internet. Thanks a lot!
int myGlobal;
void increment(int input)
{
input++;
}
void decrement(int input)
{
input--;
}
int doSomething(int input, int op)
{
if (op)
{
increment(input);
}
else
{
decrement(input);
}
}
int main(void)
{
int i, currMax;
int myOp = 1;
myGlobal = 0;
currMax = 5;
for (i = 0; i < currMax; i++)
{
doSomething(myGlobal, myOp);
}
currMax = 4;
myOp = 0;
for (i = 0; i < currMax; i++)
{
doSomething(myGlobal, myOp);
}
}
BECOMES
int main(void)
{
int i, currMax;
int myOp = 1;
myGlobal = 0;
currMax = 5;
for (i = 0; i < currMax; i++)
{
// doSomething(myGlobal, myOp);
if (myOp)
{
// increment(myGlobal);
myGlobal++;
}
else
{
decrement(myGlobal);
myGlobal--;
}
}
currMax = 4;
myOp = 0;
for (i = 0; i < currMax; i++)
{
// doSomething(myGlobal, myOp);
if (myOp)
{
// increment(myGlobal);
myGlobal++;
}
else
{
// decrement(myGlobal);
myGlobal--;
}
}
}

Stack around the variable 'ch' was corrupted

I am in the process of writing a decipher algorithm for Vegenere Variant Cipher and ran into some C specific issues(I am not too familiar with C).
I get
"Run-Time Check Failure #2 - Stack around the variable 'ch' was corrupted" error.
If I understand the error right, ch is not available when I try to read/write to it(ch in this case represents a HEX value read from the text file, I have posted the code of the function below).
But, for the life of me, I can't figure out where it happens. I close the file way before the I exit the function(exception is thrown at the time I leave the function).
Can you take a look an let me know where I have it wrong? Thanks in advance.
P.S. I am tagging the question with C++ as well as it should pretty much be the same except, maybe, how we read the file in.
Anyways, my code below:
int getKeyLength(char *cipherTxtF){
int potKeyL = 1;
float maxFreq = 0.00;
int winKL = 1;
for (potKeyL = 1; potKeyL <= 13; potKeyL++)// loop that is going through each key size startig at 1 and ending at 13
{
unsigned char ch;
FILE *cipherTxtFi;
cipherTxtFi = fopen(cipherTxtF, "r");
int fileCharCount = 0;
int freqCounter[256] = { 0 };
int nThCharCount = 0;
while (fscanf(cipherTxtFi, "%02X", &ch) != EOF) {
if (ch != '\n') {
if (fileCharCount % potKeyL == 0){
int asciiInd = (int)ch;
freqCounter[asciiInd] += 1;
nThCharCount++;
}
}
fileCharCount++;
}
fclose(cipherTxtFi);
float frequenciesArray[256] = { 0 };
float sumq_iSq = 0;
int k;
for (k = 0; k < 256; k++){
frequenciesArray[k] = freqCounter[k] / (float)nThCharCount;
}
for (k = 0; k < 256; k++){
sumq_iSq += frequenciesArray[k] * frequenciesArray[k];
printf("%f \n", sumq_iSq);
}
if (maxFreq < sumq_iSq) {
maxFreq = sumq_iSq;
winKL = potKeyL;
}
}
return winKL;
}
You are trying to read an hexadecimal integer with fscanf() (format "%02X", where X means "integer in hex format") and store it into a char.
Unfortuantely fscanf() just receives the address of the char and doesn't know that you've not provided the address of an int. As int is larger than a char, the memory gets corrupted.
A solution could be:
int myhex;
while (fscanf(cipherTxtFi, "%02X", &myhex) != EOF) {
ch = myhex;
...

Why the code block is not Autovectorized by VC2013

The code block is from mozilla firefox's qcms transform_util.c
void build_output_lut(struct curveType *trc,
uint16_t **output_gamma_lut, size_t *output_gamma_lut_length)
{
if (trc->type == PARAMETRIC_CURVE_TYPE) {
float gamma_table[256];
uint16_t i;
uint16_t *output = malloc(sizeof(uint16_t)*256);
if (!output) {
*output_gamma_lut = NULL;
return;
}
compute_curve_gamma_table_type_parametric(gamma_table, trc->parameter, trc->count);
*output_gamma_lut_length = 256;
for(i = 0; i < 256; i++) {
output[i] = (uint16_t)(gamma_table[i] * 65535);
}
*output_gamma_lut = output;
} else {
if (trc->count == 0) {
*output_gamma_lut = build_linear_table(4096);
*output_gamma_lut_length = 4096;
} else if (trc->count == 1) {
float gamma = 1./u8Fixed8Number_to_float(trc->data[0]);
*output_gamma_lut = build_pow_table(gamma, 4096);
*output_gamma_lut_length = 4096;
} else {
//XXX: the choice of a minimum of 256 here is not backed by any theory,
// measurement or data, however it is what lcms uses.
*output_gamma_lut_length = trc->count;
if (*output_gamma_lut_length < 256)
*output_gamma_lut_length = 256;
*output_gamma_lut = invert_lut(trc->data, trc->count, *output_gamma_lut_length);
}
}
}
For this loop:
for(i = 0; i < 256; i++) {
output[i] = (uint16_t)(gamma_table[i] * 65535);
}
VC2013 will show:
e:\mozilla\hg\nightly\mozilla-central\gfx\qcms\transform_util.c(490) : info C5002: 由于“500”,循环未向量化
MSDN (http://msdn.microsoft.com/en-us/library/jj658585.aspx) shows:
// Code 500 is emitted if the loop has non-vectorizable flow.
// This can include "if", "break", "continue", the conditional
// operator "?", or function calls.
// It also encompasses correct definition and use of the induction
// variable "i", in that the increment "++i" or "i++" must be the last
// statement in the loop.
But the loop above has no if/break/continue, I don't know why it can't be vectorized.
I suspect that this is due to the fact that variable "i" lies in scope of "if"-statement. Thus it does not belong entirely to "for-loop" scope like it would have been in
for(int i = 0; /* etc. */
At such, the compiler's logic would have been like: "I need not only to make gammatable filles with needed values, but to assign same value to "i" as at loop end". Therefore, no vectorization.

C - Nested for loops not printing multiple elements

My nested loops only print one char, 'c', which is the correct first char to print, but I cannot figure out why my loop won't keep looping through the alphabet. Any assistance in determining my loop error would be great.
#include <stdio.h>
#include <stdlib.h>
void problem_1_function();
int main(){
problem_1_function();
return (0);
}
void problem_1_function(){
FILE *the_cipher_file;
the_cipher_file = fopen("cipher.txt", "r");
FILE *the_message_file;
the_message_file = fopen("message.txt", "r");
FILE * the_decode_file;
the_decode_file = fopen("decode.txt", "w");
int the_letter_counter = 0;
int the_alphabet_array[100];
int size_of_alphabet = 0;
int size_of_message = 0;
int the_message_counter = 0;
int the_message_array[100];
char the_decode_array [15];
char the_letter_char[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','w','x','y','z'};
if(the_decode_file == NULL){
printf("Error opening file!\n");
}
if(!the_cipher_file){
printf("Error: Filename \"cipher.txt\" not found!\n");
}
while(fscanf(the_cipher_file, " %d%*[,] ", &size_of_alphabet) > 0 && the_letter_counter < 100){
the_alphabet_array[the_letter_counter] = size_of_alphabet;
//printf("%d ", size_of_alphabet);
the_letter_counter++;
}
if(!the_message_file){
printf("Error: Filename \"cipher.txt\" not found!\n");
}
while(fscanf(the_message_file, " %d%*[,] ", &size_of_message) > 0 && the_message_counter < 100){
the_message_array[the_message_counter] = size_of_message;
//printf("%d ", size_of_message);
the_message_counter++;
}
int message_equals_cipher = 0;
int message_equals_cipher2 = 0;
for(message_equals_cipher; message_equals_cipher < sizeof(the_message_array); message_equals_cipher++){ //these nested loops go through the alphabet to print letters corresponding to arrays...
for(message_equals_cipher2; message_equals_cipher2 < 26; message_equals_cipher2++){
if(the_message_array[message_equals_cipher] == the_alphabet_array[message_equals_cipher2]){
the_decode_array[message_equals_cipher] = the_letter_char[message_equals_cipher2];
fprintf(the_decode_file, "%c", the_decode_array[message_equals_cipher]);
}
}
}
fclose(the_cipher_file);
fclose(the_message_file);
fclose(the_decode_file);
}
int message_equals_cipher = 0;
int message_equals_cipher2 = 0;
for(message_equals_cipher; ...
for(message_equals_cipher2; ...
You're setting these to 0 outside the loops .. the initialization expressions of your for statements don't do anything -- if you set your warning level high enough, your compiler should tell you that. Because you don't reset message_equals_cipher2, your inner loop will only run once total. You want
for(message_equals_cipher = 0; ...
for(message_equals_cipher2 = 0; ...
If you are compiling C99 or higher, you can do
for(int message_equals_cipher = 0; ...
for(int message_equals_cipher2 = 0; ...
and get rid of the previous definitions of those variables.
Yes, the problem in your nested for loop is that you are not initializing your message_equals_cipher2 variable to 0 in your second for loop.
The nested code should be like :
for(message_equals_cipher; message_equals_cipher < sizeof(the_message_array); message_equals_cipher++)
{
for(message_equals_cipher2=0; message_equals_cipher2 < 26; message_equals_cipher2++)
{
// Your stuff
}
}
I will agree with jim, instead of initializing your variables message_equals_cipher and message_equals_cipher2 before nested for loops. You can do it as jim specified.

Initializing Strings in an Array of Sturts within a Struct

I have a struct gradebook with(among other things) an array of student structs that has two string fields
#define MAX_NAME_LEN 50
#define MAX_EMAIL_LEN 80
#define MAX_NUMBER_OF_STUDENTS 200
#define MAX_NUMBER_OF_ASSIGNMENTS 100
typedef struct students {
char *name;
char *email;
} Students;
typedef struct gradebook {
int number_of_students;
Students students[MAX_NUMBER_OF_STUDENTS];
int number_of_assignments;
char assignments[MAX_NUMBER_OF_ASSIGNMENTS][(MAX_NAME_LEN + 1)];
int scores[MAX_NUMBER_OF_STUDENTS][MAX_NUMBER_OF_ASSIGNMENTS];
} Gradebook;
I have an initialization function
int init_gradebook(Gradebook *book) {
int row, col, ndx, count;
book->number_of_students = 0;
count += book->number_of_students;
for(ndx = 0; ndx < MAX_NUMBER_OF_STUDENTS; ndx++) {
book->students[ndx].name = 0;
book->students[ndx].email = 0;
}
book->number_of_assignments = 0;
count += book->number_of_assignments;
for(row = 0; row < MAX_NUMBER_OF_ASSIGNMENTS; row++) {
for(col = 0; col < (MAX_NAME_LEN + 1); col++) {
book->assignments[row][col] = 0;
count += book->assignments[row][col];
}
}
for(row = 0; row < MAX_NUMBER_OF_STUDENTS; row++) {
for(col = 0; col < MAX_NUMBER_OF_ASSIGNMENTS; col++) {
book->scores[row][col] = 0;
count += book->scores[row][col];
}
}
if (count == 0) {
return 1;
} else {
return 0;
}
}
and I need to then insert, into those two string fields, the passed in strings, with my add_student function.
int add_student(Gradebook *book, char *nom, char *mail) {
int ndx, count;
if (book->number_of_students == 0) {
book->students[(book->number_of_students)].name = malloc(sizeof(51));
book->students[(book->number_of_students)].email = malloc(sizeof(81));
strcpy(book->students[(book->number_of_students)].name, nom);
strcpy(book->students[(book->number_of_students)].email, mail);
book->number_of_students++;
} else {
for (ndx = 0; ndx < book->number_of_students; ndx++) {
book->students[(book->number_of_students)].name = malloc(sizeof(51));
book->students[(book->number_of_students)].email = malloc(sizeof(81));
strcpy(book->students[(book->number_of_students)].name, nom);
strcpy(book->students[(book->number_of_students)].email, mail);
book->number_of_students++;
}
}
return 1;
}
My code compiles, but when I run it with the main function, I get a seg fault. The add_student function is what I am ultimately trying to do (copy the given string into book->student[ndx].name) If you need to see the main file or the gradebook.h file, let me know.
Edit: Thanks to all of you, this issue has been solved. The main problem, as abginfo pointed out, was my If Else + the For loop inside of it. But now I have other problems further along in my program. Haha, Thank You.
From what portion of your code I can see, I'm going to make the assumption that the init_gradebook function takes a non allocated reference to gradebook and attempts to initialize it.
In this case the gradebook reference you have has no memory allocated to it just yet. Try using the malloc() function to assign the required memory to your gradebook reference before attempting to initialize the rest of its variables.
gb = (Gradebook*)malloc(sizeof(*Gradebook));
I've changed the variable name to avoid any confusion.
To supplement varevarao's answer, you should allocate everything explicitly as a matter of habit instead of relying on segfaults to tell you something's not allocated. (Not that you necessarily do!) Messing with unallocated memory is undefined behavior, so in some cases this code does not trigger an error -
int main (void) {
Gradebook mybook;
init_gradebook(&mybook);
printf("there are %i students\n", mybook.number_of_students);
add_student(&mybook, "blerf", "blerf#gmail.com");
printf("now there are %i students\n", mybook.number_of_students);
printf("%s has an email address of %s\n", mybook.students[0].name, mybook.students[0].email);
return 0;
}
returned (on my machine)
there are 0 students
now there are 1 students
blerf has an email address of blerf#gmail.com

Resources