I wrote this code to merge two sorted arrays. The desired output is:
Merged array:0 1 2 3 4 5 6 7 8 9 10 11 12
I am using gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609 to compile my code.
The problem is that sometimes I get the desired output when I execute the a.out file but on other occasions, the cursor keeps blinking and no result is shown. Why is this happening? Is there something wrong with my code?
#include<stdio.h>
#include<stdlib.h>
int main(void){
//change arrays as per your need but it should be sorted
int a[] = {1,2,3,7,8};
int b[] = {0,3,5,6,9,10,11,12};
int m =sizeof(a) / sizeof(int);
int n =sizeof(b) / sizeof(int);
int index=0, j=0, k=0;
int size = m + n;
int array[size];
while(index < size) {
while(a[j] < b[k] && j<m ){
array[index] = a[j];
++index;
++j;
}
while(a[j] > b[k] && k<n){
array[index] = b[k];
++index;
++k;
}
while(a[j] == b[k]){
array[index] = a[j];
j++; index++;
}
}
printf("Merged array: ");
for(int i=0; i<size; i++)
printf("%d ", array[i]);
printf("\n");
}
You have undefined behaviour (accessing the array out of bounds). Use gcc -fsanitize=undefined to create an executable that can detect all sorts of bad behaviour.
% gcc -g fffff.c -Wall -Wextra -fsanitize=undefined
% ./a.out
fffff.c:20:12: runtime error: index 5 out of bounds for type 'int [5]'
fffff.c:20:12: runtime error: load of address 0x7ffd0c0c9804 with insufficient space for an object of type 'int'
0x7ffd0c0c9804: note: pointer points here
08 00 00 00 04 00 00 00 04 00 00 00 04 00 00 00 00 00 00 00 03 00 00 00 05 00 00 00 06 00 00 00
^
fffff.c:25:12: runtime error: index 5 out of bounds for type 'int [5]'
fffff.c:25:12: runtime error: load of address 0x7ffd0c0c9804 with insufficient space for an object of type 'int'
0x7ffd0c0c9804: note: pointer points here
08 00 00 00 04 00 00 00 04 00 00 00 04 00 00 00 00 00 00 00 03 00 00 00 05 00 00 00 06 00 00 00
^
fffff.c:30:12: runtime T: index 5 out of bounds for type 'int [5]'
fffff.c:30:12: runtime error: load of address 0x7ffd0c0c9804 with insufficient space for an object of type 'int'
0x7ffd0c0c9804: note: pointer points here
08 00 00 00 04 00 00 00
The lines 20, 25 and 30 are
20 while(a[j] < b[k] && j<m ){
25 while(a[j] > b[k] && k<n){
30 while(a[j] == b[k]){
Is there something wrong with my code?
Yes!
It gets out of bounds when accessing a, here for example:
while(a[j] < b[k] && j<m ){
array[index] = a[j];
++index;
++j;
}
j will eventually get the value 4, enter the body of the if statement, and when it tries to resolve the condition of the while loop, it will access a[5], which is out of bounds, thus causing Undefined Behavior (which explains why your code runs sometimes, and others hang).
You could let short circuiting help you by changing your while loop's condition to this:
while(j < m && a[j] < b[k]) {
which when j reaches mm, resulting in j<m evaluated to false, will not go through a[j] < b[k], because a logical and operation will be false, if at least one of its operands are false.
Same happens in your next while loop. So change it to this:
while(k < n && a[j] > b[k]) {
Last, but not least, the condition of the last while loop:
while(a[j] == b[k]){
will also invoke Undefined Behavior, since j will be equal to 5, and k equal to 8.
Changing it to:
while(j < m && k < n && a[j] == b[k]) {
will prevent Undefined Behavior from being invoked.
Related
Given a byte array buff of length n:
unsigned char buff[n] = "....." // len n
I want to delete m characters at position pos,
0 < pos, m, pos + m < n
I tried using memmove:
memmove(buff + pos, buff + pos + m, n - (pos + m) + 1);
But this doesn't work for byte array as we don't have '\0' terminator for this buff (but we know its length)
How do I delete bytes in between? Anyone please help
Edit: Sample input,
Pos Data
0000 03 00 02 ef 02 f0 80 64 00 08 03 eb 70 82 e0 40
0010 00 ff 30 00 00 00 00 b3 47 43 00 00 00 00 00 00
0020 00 1e 00 c4 00 00 00 00 00 00 00 44 00 65 00 66
0030 00 61 00 75 00 6c 00 74 00 41 00 6c 00 74 00 53
Say I want to delete the highlighted bytes from packet.
New paket,
Pos Data
0000 03 00 02 ef 02 f0 80 64 00 08 03 00 00 00 00 00
0010 00 00 44 00 65 00 66 00 61 00 75 00 6c 00 74 00
0020 41 00 6c 00 74 00 53
This would erase m chars in an array without terminating null character.
int main()
{
int pos = 1, m = 3;
unsigned char arr[8] = {1,2,3,4,5,6,7,8};
memmove(arr + pos, arr + pos + m, sizeof(arr)/sizeof(arr[0]) - pos - m);
// if required to zero-out the remaining elements
memset(arr + sizeof(arr)/sizeof(arr[0]) - m, 0, m);
for (int i = 0; i < sizeof(arr)/sizeof(arr[0]); i++)
printf("%hhu ", arr[i]);
return 0;
}
Output: 1 5 6 7 8 0 0 0
You probably want something like this:
#include <stdio.h>
#include <string.h>
void Display(const char buff[], int nb)
{
for (int i = 0; i < nb; i++)
printf("%d ", buff[i]);
printf("\n");
}
int main()
{
unsigned char buff[20] = { 0,1,2,3,4,5 };
// buff has room for 20 elements
int nbelements = 6; // but there are only 6 meaningful elements
Display(buff, nbelements);
int pos = 1; // delete from element 1
int nbtodelete = 2; // delete 2 elements
memmove(buff + pos, buff + pos + nbtodelete, nbelements - pos - 1);
nbelements -= nbtodelete;
Display(buff, nbelements);
}
Output:
0 1 2 3 4 5
0 3 4 5
It's pretty self explanatory.
I am creating a 2D array using malloc and when I iterate through the array there are characters and symbols that I do not want in there. Shouldn't the array be completely empty?
I have tried to assign the null character to the beginning of each row but that doesn't change anything.
char **structure;
structure = malloc(sizeof *structure * 2);
if (structure) {
for (size_t i = 0; i < 2; i++) {
structure[i] = malloc(sizeof *structure[i] * 20);
structure[i][0] = '\0';
}
}
for (int i = 0; i <= 2; i++) {
for (int j = 0; j < 20; j++) {
printf("%c ", structure[i][j]);
}
printf("\n");
}
I expected the output to just be blank spaces but this is what appeared:
Z Ñ P Ñ l L O
Z Ñ P Ñ N U M B
You should use the calloc function; this is what I often use. It does the same work as malloc() but it initializes all allocated bits with 0.
calloc documentation
As you are accessing each character you must clear all position explicitly to get your desired output.
char **structure;
structure = (char**)malloc( (sizeof *structure) * 2 );
if (structure)
{
for(size_t i = 0; i < 2; i++){
// structure[i];
structure[i] =(char *) malloc( sizeof *structure[i] * 20 );
for(int j=0; j<20; j++)
structure[i][j] = '\0';
}
}
for(int i = 0; i < 2; i++){ //you can not access position i==2
for(int j = 0; j < 20; j++)
{
printf("%c ", structure[i][j]);
}
printf("\n");
}
You can also use printf("%s", structure[i]) to make it work with your current code. it will work because you have made first position of both strings NULL('\0').So printf function will terminate for both character arrays without printing anything. But remember, other position than the first one of both arrays will contain garbage value.
When you are allocating memory the data inside the memory is undefined. the malloc function just giving you the memory.
if you want the memory to be initialized to 0 you can always use the standard calloc function.
If you want to initialize it after allocation you can always use the memset function. in your case
memset(structure, 0, (sizeof *structure) * 2)
You are not really allocating a 2D array of char, but an array of 2 pointers to arrays of 20 char. It is much simpler to allocate a true 2D array:
// allocate a 2D array and initialize it to null bytes
char (*structure)[20] = calloc(sizeof(*structure), 2);
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 20; j++) {
printf("%02X ", structure[i][j]);
}
printf("\n");
}
Output:
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
I want to create a function in c, which creates every 8 increments (to be exact, when an integer holds the value 8) a paragraph/new line (and also prints an offset).
In this case, i've got an array
for (int i = 0; i < sizeof(myarray); i++){
printf(" %02hhX", myarray[i]);
}
Now i want to implement my function like this
int row = 0;
for (int i = 0; i < sizeof(myarray); i++){
printf(" %02hhX", myarray[i]);
check_newline(row);
}
The function 'check_newline' has this structure:
void check_newline(int row){
row++;
if(row==8){
offset = offset + 8;
row= 0;
printf("\n%06X", offset);
}
}
Everytime, the integer 'row' reaches the value 8 a new offset will be printed and the value of 'row' will be reset to 0.
Now, i don't know how to implement the return; and with this code, my output looks like this
000008 E0 60 66 64 38 7D E0 60 66 64 38 7D 80000008 80 00 FF FF FF FF FF FF 000010 E0 60 66 64 38 7D E0 60 66 64 38 7D 80000010 80 00 FF FF FF FF FF FF
(totaly wrong)
When i 'put the function inside my code' (so basicaly don't use a function), everything is nice, because of the missing return statement.
for (int i = 0; i < sizeof(myarray); i++){
printf(" %02hhX", myarray[i]);
row++;
if(row==8){
offset = offset + 8;
row= 0;
printf("\n%06X", offset);
}
000000 80 00 FF FF FF FF FF FF
000008 E0 60 66 64 38 7D E0 60
I have to use this kind of calculation often in my code, so a function will be more sleek.
You are over complicating things. You don't need the extra variables as you can make use of i and the % (modulo operator) to work out when you're at the beginning or end of a row like this.
for (int i = 0; i < sizeof(myarray); i++) {
if (i % 8==0) {
printf("%06X",i);
}
printf(" %02hhX", myarray[i]);
if (i % 8==7) {
printf("\n");
}
}
I am trying to convert a hexadecimal data coming from a port( stored in a buffer) into integer format using C program. Before converting from buffer, I wanted to test my code by giving some input in the program. The following is the program I am using from a online source.
#include <stdio.h>
#include <stdlib.h>
int hexToInt(char s[]) {
int hexdigit, i, inhex, n;
i=0;
if(s[i] == '0') {
++i;
if(s[i] == 'x' || s[i] == 'X'){
++i;
}
}
n = 0;
inhex = 1;
for(; inhex == 1; ++i) {
if(s[i] >= '0' && s[i] <= '9') {
hexdigit = s[i] - '0';
} else if(s[i] >= 'a' && s[i] <= 'f') {
hexdigit = s[i] - 'a' + 10;
} else if(s[i] >= 'A' && s[i] <= 'F') {
hexdigit = s[i] - 'A' + 10;
} else {
inhex = 0;
}
if(inhex == 1) {
n = 16 * n + hexdigit;
}
}
return n;
}
int main(int argc, char** argv) {
char hex[] = "93 BC";
int digit = hexToInt(hex);
printf("The Integer is %d", digit);
return 0;
}
When I run this program, it converts one input of hexadecimal into a integer. But if I had to convert an array of hex input as listed below:
00 00 00 05 00 00 00 01 93 BC C0 06 00 00 00 00 ................
00 28 17 00 FC 26 CC 62 00 00 00 07 00 00 00 01 .(...&.b........
00 00 00 D0 00 E3 37 19 00 00 00 1D 00 00 01 00 ......7.........
AB B6 CD 14 00 11 1F 3C 00 00 00 1D 00 00 00 00 .......<........
00 00 00 02 00 00 00 01 00 00 00 90 00 00 00 01 ................
00 00 05 EE 00 00 00 04 00 00 00 80 F0 92 1C 48 ...........�...H
C2 00 00 0E 0C 30 C7 C7 08 00 45 00 05 DC 32 70 .....0....E...2p
40 00 2D 06 41 C8 2D 3A 4A 01 93 BC C8 EC 01 BB #.-.A.-:J.......
C1 58 C5 8D 53 88 05 72 46 E6 80 10 00 53 DC 34
Then how I can convert it into corresponding integer values?
"to convert of array of hex input", modify hexToInt() to hexToInt(const char *s, char **endptr) and have it set *endptr to where the parsing stopped. If no parsing occurred, have *endptr = s.
int main(void) {
char hex[] = "93 BC";
char *p = hex;
while (*p) {
char *endptr;
int digit = hexToInt(p, &endptr);
if (p == endptr) break;
printf("The Integer is %d", digit);
p = endptr;
}
return 0;
}
I am trying to write a program that will talk to a XBee Pro S2B over serial from a PIC16 and I have some odd memory stuff going on...
I am a bit weak when it comes to pointers in C so I have been writing a test program using GCC to get it to work before I move it over to the PIC microcontroller. The biggest thing to note with the PIC is the memory constraints. So for this I would like to avoid adding any external libraries unless I absolutely have to (and avoid having to use malloc/free).
Here is my code:
#include <stdio.h>
#define FALSE 0
#define TRUE 1
void printPacketArray(unsigned char *packetArray, int packetSize){
printf("OUTPUT PACKET: ");
for(int i = 0; i < packetSize; i++){
printf("%02X ", packetArray[i]);
}
printf("\n");
}
/**
* This function builds all of the frames to be wrapped into a packet
*/
int buildFrame(
unsigned char frameType,
unsigned char requestResponse,
unsigned char *destinationAddress64Bit,
unsigned char *destinationAddress16Bit,
unsigned char *rfPacketData,
int destinationAddress64BitSize,
int destinationAddress16BitSize,
int rfDataSize,
unsigned char **frameArray,
int **frameArraySize){
// printf("Entering buildFrame\n");
// FT RESP (Optional Dest Addr x64) + (Optional Dest Addr x16) Packet
int outputPacketSize = (1 + 1 + destinationAddress64BitSize + destinationAddress16BitSize + rfDataSize);
// printf("Packet Size: %d\n", outputPacketSize);
unsigned char outputPacketArray[outputPacketSize];
// Add the frame type
outputPacketArray[0] = frameType;
// printf("Frame type: %02X\n", frameType);
// Request response
outputPacketArray[1] = requestResponse;
// printf("Response: %02X\n", requestResponse);
int arrayCount = 2;
// Add the destination address (64 bit)
if(destinationAddress64Bit != 0x00){
for(int i = 0; i < 8; i++){
outputPacketArray[arrayCount] = destinationAddress64Bit[i];
// printf("outputPacketArray[%d] = %02X\n", arrayCount, destinationAddress64Bit[i]);
arrayCount++;
}
}
// Ad the destination address (16 bit)
if(destinationAddress16Bit != 0x00){
for(int i = 0; i < 2; i++){
outputPacketArray[arrayCount] = destinationAddress16Bit[i];
// printf("outputPacketArray[%d] = %02X\n", arrayCount, destinationAddress16Bit[i]);
arrayCount++;
}
}
// Add the packet data
for(int i = 0; i < rfDataSize; i++){
outputPacketArray[arrayCount] = rfPacketData[i];
// printf("outputPacketArray[%d] = %02X\n", arrayCount, rfPacketData[i]);
arrayCount++;
}
*frameArray = outputPacketArray;
// printf("*frameArray = %p\n", outputPacketArray);
*frameArraySize = &outputPacketSize;
// printf("*frameArraySize = %p\n", &outputPacketSize);
// printf("Packet: ");
// for(int i = 0; i < outputPacketSize; i++){
// printf("%02X ", outputPacketArray[i]);
// }
// printf("\n");
// printf("Exiting buildFrame\n");
return TRUE;
}
/**
* This function wraps the frame data into the packet.
*/
int buildPacket(
unsigned char *frameData,
int frameDataSize,
unsigned char **packetArrayPtr,
int **packetArraySizePtr){
// 7E MSB LSB Packet Checksum
int outputPacketSize = (1 + 1 + 1 + frameDataSize + 1);
int checksum = 0;
unsigned char outputPacketArray[outputPacketSize];
// Add the start delimiter
outputPacketArray[0] = 0x7E;
// Add the MSB (should always be 0x00)
outputPacketArray[1] = 0x00;
// Add the LSB (size of frameData)
outputPacketArray[2] = frameDataSize;
// Add the frame data
int arrayCount = 3;
for(int i = 0; i < frameDataSize; i++){
// printf("CNT: %d\n", arrayCount);
outputPacketArray[arrayCount] = frameData[i];
checksum += frameData[i];
arrayCount++;
}
// Add the checksum
outputPacketArray[arrayCount] = (0xFF - (checksum & 0xFF));
// printf("CNT: %d\n", arrayCount);
// printf("Packet: ");
// for(int i = 0; i < outputPacketSize; i++){
// printf("%02X ", outputPacketArray[i]);
// }
// printf("\n");
*packetArrayPtr = outputPacketArray;
*packetArraySizePtr = &outputPacketSize;
return TRUE;
}
int sendAPICommand(unsigned char* inputFrameData, int inputFrameDataLength){
unsigned char destinationAddress64Bit[] = {0x00, 0x13, 0xA2, 0x00, 0x40, 0x9C, 0x26, 0xE1};
unsigned char destinationAddress16Bit[] = {0xFF, 0xFE};
unsigned char *frameArrayPtr = 0x00;
int *frameArraySizePtr = 0x00;
// printf("COMPARE: 7E 00 13 10 01 00 13 A2 00 40 9C 26 E1 FF FE 00 00 01 02 03 04 05 4A\n");
// We need to add in the radius and options before the data
unsigned char frameData[(inputFrameDataLength + 2)];
frameData[0] = 0x00; // Radius
frameData[1] = 0x00; // Options
for(int i = 0; i < inputFrameDataLength; i++){
frameData[(i + 2)] = inputFrameData[i];
}
if(buildFrame(0x10, 0x01, destinationAddress64Bit, destinationAddress16Bit, frameData, 8, 2, (inputFrameDataLength + 2), &frameArrayPtr, &frameArraySizePtr) == TRUE){
printf("COMPARE: 10 01 00 13 A2 00 40 9C 26 E1 FF FE 00 00 01 02 03 04 05\n");
printPacketArray(frameArrayPtr, *frameArraySizePtr);
// The building of the frame was a success
if(buildPacket(frameArrayPtr, *frameArraySizePtr, &frameArrayPtr, &frameArraySizePtr) == TRUE){
printf("COMPARE: 7E 00 13 10 01 00 13 A2 00 40 9C 26 E1 FF FE 00 00 01 02 03 04 05 4A\n");
printPacketArray(frameArrayPtr, *frameArraySizePtr);
return TRUE;
}
}
return FALSE;
}
int main(){
unsigned char packetData[] = {0x01, 0x02, 0x03, 0x04, 0x05};
sendAPICommand(packetData, 5);
return 0;
}
When I run it, I cannot seem to find out why the results are not consistent. Using the Eclipse debugger, I get the following error:
frameData.15 Error: Multiple errors reported.\ Failed to execute MI command: -var-create - * frameData.15 Error message from debugger back end: mi_cmd_var_create: unable to create variable object\ Failed to execute MI command: -var-create - * frameData.15 Error message from debugger back end: mi_cmd_var_create: unable to create variable object\ Failed to execute MI command: -data-evaluate-expression frameData.15 Error message from debugger back end: No symbol "frameData" in current context.\ Failed to execute MI command: -var-create - * frameData.15 Error message from debugger back end: mi_cmd_var_create: unable to create variable object\ Unable to create variable object
on this line of code:
if(buildFrame(0x10, 0x01, destinationAddress64Bit, destinationAddress16Bit, frameData, 8, 2, (inputFrameDataLength + 2), &frameArrayPtr, &frameArraySizePtr) == TRUE){
When I run the program completely (it silently fails) and this is my text output:
COMPARE: 10 01 00 13 A2 00 40 9C 26 E1 FF FE 00 00 01 02 03 04 05
OUTPUT PACKET: 01 00 00 00 00 00 00 00 D8 8C 28 03 01 00 00 00 B0 8A 97 5C FF 7F 00 00 08 00 00 00 00 00 00 00 00 8A 97 5C 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF 00 00 00 00 00 00 00 00 00 00 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00 00 00 30 00 00 00 90 8A 97 5C FF 7F 00 00 90 89 97 5C FF 7F 00 00 00 00 00 00 00 00 00 00
I suspect the problem is I have a bad pointer (or pointers) in returning the size or the pointer to the character array but I don't know that for sure (or know how to get the program to fail in a way I can determine it).
In buildFrame:
unsigned char outputPacketArray[outputPacketSize];
outputPacketArray is a local variable. Its lifetime ends when you leave the function. However you assign a pointer to it to an output parameter of the function:
*frameArray = outputPacketArray;
(Same for outputPacketSize)
These pointers do not point to valid memory anymore when you leave the function. You need to dynamically allocate the array:
unsigned char* outputPacketArray = malloc(outputPacketSize);
and then free it later. Alternatively you could provide an appropriately sized array to the function, but then you would need to calculate the size already in main.
For the size you don't need a pointer to pointer at all, just return it from the function, or use a simple pointer (instead of double pointer) as output parameter.