I have a problem with segmentation fault. And I am not sure about the arrays.
I need to get output like this
Here is part of my code. (structure and enumeration must stay unchanged)
EDIT: second malloc fix, This is only part of my code where I get segmentation fault, warning while compiling: unused variable ‘title’ and segmentation fault while running
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
typedef enum {
GAME1,
GAME2,
GAME3,
} TITLE;
typedef struct abx {
TITLE **title;
} ABX;
string[]="ABCACC|ACCBAA|BBCABC"
ABX *abx = (ABX*)malloc(sizeof(ABX));
TITLE **title = (TITLE**)malloc(sizeof(TITLE*));
width = height = 0;
while (string[i] !='\0') {
abx->title[height][width]=(TITLE)malloc(sizeof(TITLE*));
if(string[i]=='A'){
abx->title[height][width] = GAME1;
break;
}
if(string[i]=='B'){
abx->title[height][width] = GAME2;
break;
}
if(string[i]=='C'){
abx->title[height][width] = GAME3;
break;
}
if (string[i]=='|'){
height++;
width = 0;
}
else{
width++;
}
i++;
}
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
typedef enum {
GAME1,
GAME2,
GAME3,
} TITLE;
typedef struct abx {
TITLE **title;
} ABX;
int main(){
char string[]="ABCACC|ACCBAA|BBCABC";
ABX *abx = malloc(sizeof(ABX));
int i, len, w, h, width, height;
char ch;
len = width = height = 0;
for(i=0;(ch=string[i]) != '\0';++i){
if(ch == '|'){
++height;
if(width<len)
width = len;
len = 0;
} else
++len;
}
++height;
if(width<len)
width = len;
abx->title =malloc(height*sizeof(TITLE*));
for(h=0;h<height;++h)
abx->title[h]=malloc(width*sizeof(TITLE));
for(h=w=i=0;string[i]!='\0';++i){
if(string[i]=='A'){
abx->title[h][w++] = GAME1;
continue;
}
if(string[i]=='B'){
abx->title[h][w++] = GAME2;
continue;
}
if(string[i]=='C'){
abx->title[h][w++] = GAME3;
continue;
}
if (string[i]=='|'){
++h;
w = 0;
}
}
...
}
Related
I'm developing a micro-game in c using the ncurses library for the front-end.
I simplified the code to the minimum, the expected result should be a shuttle that periodically shoots one bomb.
The problem is that when the program runs, the first shoot is always duplicated then sometimes the problem occurs again.
There are 2 processes that communicate through a pipe.
Here is a minimal version of the program to highlight the error:
#include <curses.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define ENEMYSPRITE "()"
#define BOMB "#"
typedef struct {
char * c;
int x;
int y;
int oldx;
int oldy;
}
pos;
void bombe(int pipeout, pos pos_enemy) {
pos pos_bomba;
pos_bomba.c = BOMB;
pos_bomba.x = pos_enemy.x;
pos_bomba.y = pos_enemy.y + 1;
write(pipeout, & pos_bomba, sizeof(pos_bomba));
while (1) {
pos_bomba.oldy = pos_bomba.y;
pos_bomba.oldx = pos_bomba.x;
pos_bomba.y++;
write(pipeout, & pos_bomba, sizeof(pos_bomba));
usleep(150000);
}
_exit(0);
}
void gameBoard(int pipein) {
pos pos_enemy, pos_bomba, readValue;
while (1) {
read(pipein, & readValue, sizeof(readValue));
if (strcmp(readValue.c, BOMB) == 0) {
mvaddstr(pos_bomba.oldy, pos_bomba.oldx, " "); // deleting the old bullet's position
pos_bomba = readValue;
}
mvaddstr(readValue.y, readValue.x, readValue.c);
refresh();
}
}
void enemy(int pipeout) {
pid_t pid_bomba;
pos pos_enemy;
pos_enemy.c = ENEMYSPRITE;
pos_enemy.x = 10;
pos_enemy.y = 5;
write(pipeout, & pos_enemy, sizeof(pos_enemy));
while (1) {
pid_bomba = fork();
if (pid_bomba == 0) {
bombe(pipeout, pos_enemy);
}
write(pipeout, & pos_enemy, sizeof(pos_enemy));
usleep(1000000);
}
}
int main(int argc, char ** argv) {
initscr();
noecho();
curs_set(0);
int fdescriptor[2];
pipe(fdescriptor);
pid_t pidEnemy = fork();
if (pidEnemy == 0) {
close(fdescriptor[0]);
enemy(fdescriptor[1]);
} else {
close(fdescriptor[1]);
gameBoard(fdescriptor[0]);
}
return 0;
}
I believe the problem with our code is inside function bombe(). Here is the revision that fixed the problem of initially it shoots twice.
void bombe(int pipeout, pos pos_enemy) {
pos pos_bomba = pos_enemy;
pos_bomba.c = BOMB;
pos_bomba.y = pos_enemy.y + 1;
while (1) {
pos_bomba.oldy = pos_bomba.y;
pos_bomba.oldx = pos_bomba.x;
write(pipeout, & pos_bomba, sizeof(pos_bomba));
++pos_bomba.y;
usleep(1155000);
}
_exit(0);
}
Note that now only one write() inside this function.
Can someone please tell me why my free() function keeps triggering a breakpoint? I then get a Microsoft Visual C++ Runtime Library error: Debug Assertion failed! Program: ... .exe, File: minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp ... Expression: _CrtlsValidHeapPointer(block).
#include <winsock2.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <stdlib.h>
#pragma comment(lib, "IPHLPAPI.lib")
int main()
{
IP_ADAPTER_INFO *pAdapterInfo = malloc(sizeof(IP_ADAPTER_INFO));
if (pAdapterInfo == NULL)
{
return 1;
}
ULONG size = sizeof(*pAdapterInfo);
ULONG * pOutBufLen = &size;
if(GetAdaptersInfo(pAdapterInfo, pOutBufLen) == ERROR_BUFFER_OVERFLOW) //When this error code is returned, the pOutBufLen parameter points to the required buffer size.
{
pAdapterInfo = realloc(pAdapterInfo, *pOutBufLen);
}
else
{
return 1;
}
if(GetAdaptersInfo(pAdapterInfo, pOutBufLen) == NO_ERROR)
{
while (pAdapterInfo->Next != NULL)
{
printf("%s\n", pAdapterInfo->Description);
pAdapterInfo = pAdapterInfo->Next;
}
}
free(pAdapterInfo);
getchar();
return 0;
}
SOLUTION: Ok, thanks for everyone for your responses. I fixed my problem with another pointer that I've called pAdapter:
int main()
{
IP_ADAPTER_INFO *pAdapterInfo = malloc(sizeof(IP_ADAPTER_INFO));
IP_ADAPTER_INFO *pAdapter = NULL; //for memory freeing purposes only
...
if(GetAdaptersInfo(pAdapterInfo, pOutBufLen) == NO_ERROR)
{
pAdapter = pAdapterInfo;
while (pAdapter->Next != NULL)
{
printf("%s\n", pAdapter->Description);
pAdapter = pAdapter->Next;
}
}
free(pAdapterInfo);
im supposed to be able to print all of the countries in the printfunction and pass it to the second if statement, but it doesn't seem to be printing . I know it's the
printf("%s\n", ctryList[numCountries].countryName);
part but i don't know what's wrong with it.
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
const int MAX_COUNTRY_NAME_LENGTH = 50;
typedef struct CountryTvWatch_struct {
char countryName[50];
int tvMinutes;
} CountryTvWatch;
void PrintCountryNames(CountryTvWatch ctryList[], int numCountries)
{
int i;
for(i = 0; i < numCountries; i++)
{
printf("%s\n", ctryList[numCountries].countryName);
}
return;
}
int main(void) {
// Source: www.statista.com, 2010
const int NUM_COUNTRIES = 4;
CountryTvWatch countryList[NUM_COUNTRIES];
char countryToFind[MAX_COUNTRY_NAME_LENGTH];
bool countryFound = false;
int i = 0;
strcpy(countryList[0].countryName, "Brazil");
countryList[0].tvMinutes = 222;
strcpy(countryList[1].countryName, "India");
countryList[1].tvMinutes = 119;
strcpy(countryList[2].countryName, "U.K.");
countryList[2].tvMinutes = 242;
strcpy(countryList[3].countryName, "U.S.A.");
countryList[3].tvMinutes = 283;
printf("Enter country name: \n");
scanf("%s", countryToFind);
countryFound = false;
for (i = 0; i < NUM_COUNTRIES; ++i) { // Find country's index
if (strcmp(countryList[i].countryName, countryToFind) == 0) {
countryFound = true;
printf("People in %s watch\n", countryToFind);
printf("%d minutes of TV daily.\n", countryList[i].tvMinutes);
}
}
if (!countryFound) {
printf("Country not found, try again.\n");
printf("Valid countries:\n");
PrintCountryNames(countryList, NUM_COUNTRIES);
}
return 0;
}
the following proposed code:
incorporates the comments to the question
properly checks for I/O errors
lets the user know what countries are available to chose from
is appropriately spaced, both horizontally and vertically, for readability
performs the desired functionality
cleanly compiles
documents why each header file is included
and now the proposed code:
#include <stdio.h> // scanf(), printf()
#include <stdlib.h> // exit(), EXIT_FAILURE
#include <string.h> // strcmp()
#include <stdbool.h> // bool, true, false
#define MAX_COUNTRY_NAME_LENGTH 50
#define NUM_COUNTRIES 4
struct CountryTvWatch_struct
{
char countryName[ MAX_COUNTRY_NAME_LENGTH ];
int tvMinutes;
};
typedef struct CountryTvWatch_struct CountryTvWatch;
// prototypes
void PrintCountryNames( CountryTvWatch ctryList[], int numCountries );
int main(void)
{
// Source: www.statista.com, 2010
CountryTvWatch countryList[NUM_COUNTRIES];
char countryToFind[ MAX_COUNTRY_NAME_LENGTH+1];
strcpy(countryList[0].countryName, "Brazil");
countryList[0].tvMinutes = 222;
strcpy(countryList[1].countryName, "India");
countryList[1].tvMinutes = 119;
strcpy(countryList[2].countryName, "U.K.");
countryList[2].tvMinutes = 242;
strcpy(countryList[3].countryName, "U.S.A.");
countryList[3].tvMinutes = 283;
// let user know what countries are available and how they are spelled
PrintCountryNames(countryList, NUM_COUNTRIES);
printf("Enter country name: \n");
// Note: following statement
// checks for error
// includes a MAX_CHAR modifier that is one less than
// the length of the input field
if( 1 != scanf("%49s", countryToFind) )
{
perror( "scanf failed" );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
bool countryFound = false;
for ( int i = 0; i < NUM_COUNTRIES; ++i )
{ // Find country's index
if (strcmp(countryList[i].countryName, countryToFind) == 0)
{
countryFound = true;
printf("People in %s watch\n", countryToFind);
printf("%d minutes of TV daily.\n", countryList[i].tvMinutes);
break; // exit the search loop early
}
}
if (!countryFound)
{
printf("Country not found, try again.\n");
printf("Valid countries:\n");
PrintCountryNames(countryList, NUM_COUNTRIES);
}
return 0;
}
void PrintCountryNames( CountryTvWatch ctryList[], int numCountries )
{
for( int i = 0; i < numCountries; i++ )
{
printf("%s\n", ctryList[ i ].countryName);
}
}
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
struct Position
{
char* x1[2];
char* x2[2];
};
int main(void)
{
struct Position positions[4];
struct Position p1[4];
char* p;
matrix[10][10];
if(r==0) //stores horizontal words in matrix
{
emptyH=0;
do
{
x=(rand()%size);
y=(rand()%10);
emptyH=0;
for(k=0;k<ans;k++)
{
if ( matrix[y][x+k]!='1')
{
emptyH=1;
k=ans;
} // checks whether word fits in matrix and position is empty
}
}while(emptyH);
token = strtok(words[random],search); //strtok to seperate char by char
matrix[y][x]=token;
if(x!=0)
{
p=(char)x;
p1[i].x1[0] = p;//SAVING the positions of x and y
}
else
p1[i].x1[0]='\0';
if(y!=0)
{
p=(char)y;
p1[i].x1[1]=p;
}
else
p1[i].x1[1]='\0';
x++;
while(token!=NULL)
{
token = strtok(NULL, search);
if(token!=NULL)
{
matrix[y][x]=token;
p=(char*)x;
p1[i].x2[0]=p;
p=(char*)y;
p1[i].x2[1]=p; // saving positions of x and y
x++;
positions[i] = p1[i];
}
}
}
correct=0;
do
{
puts("\nenter the word:");
scanf("%s",&name);
printf("\n Enter the start and end position of the word");
puts("\nstart:");
scanf("%s",&start);
puts("\n\tend:");
scanf("%s",&end);
for(k=0;k<4;k++)
{
if((strcmp(positions[k].x1,start)==0)&&(strcmp(positions[k].x2,end)==0))
{
puts("viola!");
correct=1;
}
else
puts("incorrect answer! try again");
}
}
while(correct!=1);
}
this is my code. however string compare always gives wrong answer.also
sometimes there is a runtime error as i store the positions in the
'p1[i].x1[0]'. any ideas why? thankyou for your help in advance.
You are not setting up your pointers properly. You do this:
p1[i].x1[0]='\0';
So you are initializing x1[0] to point to the zero address. That's bad. You need to allocate some space and init x1[0] to point to that space.
You could add:
p1[i].x1[0] = malloc(sizeof(char)); // Now x1[0] points to some allocated space.
and then you could dereference x1[0] properly:
*(p1[i].x1[0])='\0';
I want to get the string from USART1 of STM32VLDiscovery (STM32F100X4) and write an AT Command Parser from the string received from USART1.
Below are the concept that I have developed but I am not sure whether it's correct or not.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dosomethinga.h"
void dosomethingB();
void GET_AT_COMMAND(char*);
void takecommand(char *, char *);
int quit;
int main()
{ char buff[15];
char command = '\0';
quit = 0;
while(!quit)
{
printf("Enter your command: ");
scanf("%s", &buff);
if (buff[0] == 'A' && buff[1] == 'T' && buff[2] == '+')
{
GET_AT_COMMAND(buff);
}
}
}
void dosomethingB()
{
printf("dosomethingB called \n");
}
void GET_AT_COMMAND(char *text)
{
int command;
char temp[10] = "";
/*if(text[3] == 'A')
command = 1;
else if(text[3] == 'B')
command = 2;
else if(text[3] == 'Z')
command = 3;
*/
takecommand(text,temp);
if (strcmp(temp, "CALLA") == 0)
command = 1;
if (strcmp(temp, "CALLB") == 0)
command = 2;
if (strcmp(temp, "Z") == 0)
command = 3;
switch(command)
{
case 1:
dosomethingA();
break;
case 2:
printf("herehere.... \n");
dosomethingB();
break;
case 3:
printf("Exiting program.... \n");
quit = 1;
break;
default:
printf("Nothing to do here \n");
}
}
void takecommand(char *mycmd, char *hold)
{
int i;
for(i = 0; i < 10 ; i++)
{
hold[i] = mycmd[i+3];
}
}
Can anyone explain on the steps that I should do? Thanks.
Basicly you should wait an attention "AT" from the input and ignore anything before it.
For example inputs "XYZATZ\r" and "AaatZ\r" should be both handled as a "ATZ" command.
There can also be short pause between 'A' and 'T' (and all other chars of commands too), because human may type those commands.
By the default all commands end to "\r" character.
See more about AT commands from ITU-T documentation. For example from V.250 standard.
There are probably many alternative ways to implement that. The best alternative depends on your needs. If you are going to implement all AT-commands of mobile-terminal, then you should spend more time for the parser. If you want make some test application for few commands, then your implementation could be simple as your provided one.
I have developed this AT command parser, this could be use for reference.
When you get data from UART1 just call this method at_wait_msg() to parse the AT message
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
static const char *AT_HEADER = "AT";
static const char *AT_DEVICE_PROFILE = "DR";
static const char *AT_SET_DEVICE = "SD";
static const char AT_EOF = '\r';
typedef enum {
DeviceProfile,
SetDevice,
Error
} AT_Msg_Type;
typedef struct {
char header[3];
char command[3];
char data[128];
} AT_Msg_Data;
static void at_wait_msg(char text);
static void at_wait_msg_complete(char *text);
static void at_parse_msg(AT_Msg_Data *data);
static AT_Msg_Type at_check_format(AT_Msg_Data *data);
static char _rx_data[512];
static uint16_t _rx_index = 0;
int main()
{
//example data getting from UART1
char text[] = "ATDR\rATSD123456abchelloworld\r1123ATssa\r";
for (int i = 0; i < strlen(text) + 1; i++) {
//to simulate getting data from UART1 byte per byte
at_wait_msg(text[i]);
}
return 0;
}
static void at_wait_msg(char text)
{
_rx_data[_rx_index++] = text;
if (text == AT_EOF) {
at_wait_msg_complete(_rx_data);
_rx_index = 0;
}
}
static void at_wait_msg_complete(char *text)
{
AT_Msg_Data data;
int result = sscanf_s(_rx_data, "%2s%2s%s\r",
data.header, sizeof(data.header),
data.command, sizeof(data.command),
data.data, sizeof(data.data));
if (result >= 2) {
at_parse_msg(&data);
}
}
static void at_parse_msg(AT_Msg_Data *data)
{
AT_Msg_Type type = at_check_format(data);
switch (type) {
case DeviceProfile:
printf("device profile\r\n");
break;
case SetDevice:
printf("settings %s\r\n", data->data);
break;
case Error:
default:
printf("Error\r\n");
break;
}
}
static AT_Msg_Type at_check_format(AT_Msg_Data *data)
{
if (strcmp(data->header, AT_HEADER) != 0) {
return Error;
}
if (strcmp(data->command, AT_DEVICE_PROFILE) == 0) {
return DeviceProfile;
}
if (strcmp(data->command, AT_SET_DEVICE) == 0) {
return SetDevice;
}
return Error;
}