[英]stack smashing error
This is my code: 这是我的代码:
#include <mysql.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *server = "nope";
char *user = "nope";
char *password = "nope";
char *database = "nope";
unsigned int port = 0;
int cprint(char *text){//Imprime como encabezado el numero de productos sin stock sumado al argumento
MYSQL *conn;
MYSQL_RES *res;
my_ulonglong num;
conn = mysql_init(NULL);
/* Connect to database */
if (!mysql_real_connect(conn, server,
user, password, database, port, NULL, 0)) {
fprintf(stderr, "%s\n", mysql_error(conn));
exit(1);
}
/* send SQL query */
if (mysql_query(conn, "SELECT id FROM productos WHERE stock <= 0")) {
fprintf(stderr, "%s\n", mysql_error(conn));
exit(1);
}
res = mysql_store_result(conn);
num = mysql_num_rows(res);
printf("\n===============================\n\n");
if(num > 0){
printf("Productos sin stock: %llu\n",num);
}
else{
printf("No hay productos sin stock\n");
}
printf("\n===============================\n\n%s",text);
/*close connection */
mysql_free_result(res);
mysql_close(conn);
return 0;
}
char *remove_newline(char *s)
{
int len = strlen(s);
if (len > 0 && s[len-1] == '\n') // if there's a newline
s[len-1] = '\0'; // truncate the string
return s;
}
int newproduct(){
char *name = malloc(127*sizeof(char));//nombre del producto
char *desc = malloc(127*sizeof(char));//descripcion del producto
double price;//precio del producto
cprint("Agregar nuevo producto\n\n");
printf("Nombre del producto: ");
fgets(name, 127, stdin);
name = remove_newline(name);
printf("Descripcion: ");
fgets(desc, 127, stdin);
name = remove_newline(desc);
printf("Precio: ");
scanf("%e", &price);
MYSQL *conn;
conn = mysql_init(NULL);
printf("Mysql initiated\n");
if (!mysql_real_connect(conn, server,
user, password, database, port, NULL, 0)) {
fprintf(stderr, "%s\n", mysql_error(conn));
exit(1);
}
printf("connection established\n");
char rname[256];//string donde guardar el nombre con caracteres de escape
char rdesc[256];
printf("Vars declared\n");
mysql_real_escape_string(conn,rname,name,256);//se agregan los caracteres de escape
printf("name escaped\n");
mysql_real_escape_string(conn,rdesc,desc,256);
printf("desc escaped\n");
/*
char *query;//donde guardar el query
snprintf(query,1000,"INSERT INTO productos (nombre,descripcion,stock,precio) VALUES( %s,%s, 0, %e)",rname,rdesc,price);//query a enviar
if (mysql_query(conn, query)) {//enviar el query
fprintf(stderr, "%s\n", mysql_error(conn));
exit(1);
}*/
mysql_close(conn);
printf("Mysql closed\n");
return 0;
}
int main(){
printf("Sales Assistant Alpha v0.0\n");//Nombre y version del programa
unsigned int choice;//numero de eleccion del menu
char *err = NULL;//Error
while(1){//loop infinito
cprint("Menu Principal\n\n");//imprime el encabezado
printf("1-Agregar nuevo producto\n");
printf("2-Editar producto existente\n");
printf("3-Productos sin stock\n");
printf("4-Agregar pedido\n");
printf("5-Salir de la aplicacion\n\n");
if(err != NULL){//evalua si hubo un error y lo imprime
printf("%s\n",err);
err = NULL;
}
printf("Numero de eleccion: ");
scanf("%i",&choice);//pide eleccion
if (scanf("%*[^\n]") != EOF){//read and discard all non-newlines
scanf("%*c"); //then read and discard the newline
}
switch(choice){//evalua la eleccion y ejecuta la funcion correspondiente
case 1:
newproduct();
printf("returned\n");
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
exit(0);//termina el programa
break;
default:
err = "Eleccion no valida";//error
break;
}
}
return 0;
}
And the console execution: 和控制台执行:
Sales Assistant Alpha v0.0
===============================
Productos sin stock: 3
===============================
Menu Principal
1-Agregar nuevo producto
2-Editar producto existente
3-Productos sin stock
4-Agregar pedido
5-Salir de la aplicacion
Numero de eleccion: 1
===============================
Productos sin stock: 3
===============================
Agregar nuevo producto
Nombre del producto: a
Descripcion: a
Precio: 1
Mysql initiated
connection established
Vars declared
name escaped
desc escaped
Mysql closed
*** stack smashing detected ***: ./sales_assistant terminated
Aborted (core dumped)
------------------
(program exited with code: 134)
Press return to continue
i have this stack smashing thing that is unknown to me. 我有这个堆栈粉碎的东西,我不知道。 Besides that i want to know how much memory i can safely allocate without getting bus error.
除此之外,我想知道我可以安全地分配多少内存而不会出现总线错误。
IMPORTANT:when i disable the mysql_real_escape_string functions the code works normally, so the problem is there, but i dont know what the problem is. 重要提示:当我禁用mysql_real_escape_string函数时,代码正常工作,所以问题出在那里,但我不知道问题是什么。
thanks, matt. 谢谢,亚光。
edited Added the complete code and translated to english. 编辑添加完整代码并翻译成英文。 Also changed the question because i got a new error.
也改变了问题,因为我有一个新的错误。 Added debugging code.
添加了调试代码。
When you ask for a number with scanf("%i", &choice);
当你要求一个带有
scanf("%i", &choice);
的数字时scanf("%i", &choice);
(the result of which should be checked!), you leave the newline behind. (结果应该检查!),你留下换行符。 When you read a line with
fgets()
in newproduct()
, it reads the newline left behind. 当您在
newproduct()
读取带有fgets()
的行时,它会读取留下的换行符。
Ultimately, if you're doing line-based inputs, use fgets()
or readline()
(from POSIX 2008) to read the line and sscanf()
to parse the line. 最后,如果您正在进行基于行的输入,请使用
fgets()
或readline()
(来自POSIX 2008)来读取行,使用sscanf()
来解析行。
your malloc() is wrong for a (char*) 你的malloc()对于(char *)是错误的
should be: 应该:
char *name = malloc(127*sizeof(char));//nombre del producto
char *desc = malloc(127*sizeof(char));
The problem was indeed mysql_real_escape_string(). 问题确实是mysql_real_escape_string()。 the thing was that the length argument must be the *from lenght instead of the *to lenght like i was doing.
问题是,长度参数必须是*来自lenght而不是*,就像我正在做的那样。 im very happy that i worked that thing out, i was getting really frustrated.
我非常高兴我做了那件事,我真的很沮丧。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.