您好,我写了这段代码但它最终有效,“该程序已停止工作”
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
void main()
{
char *s;
s=(char*)malloc(sizeof(char));
printf("Enter a string:\n");
gets(s);
while (*s)
{
if (*s>= 65 && *s<=90)
printf("%c",*s+32);
else if(*s>=97 && *s<=122)
printf("%c",*s-32);
else
printf("%c",*s);
*s++;
}
free(s);
}
答案 0 :(得分:4)
该代码不起作用,实际上它有未定义的行为。
此:
s = (char *) malloc(sizeof(char));
分配1个字节的存储空间,然后扫描一个字符串,因此很可能导致缓冲区溢出。缓冲区只能保存一个字符串,即结尾处终结符之前的0个字符的字符串。
你的意思是:
s = malloc(128);
或类似的东西。
无需投射,sizeof (char)
始终为1,因此不会添加任何内容。
此外,作为更多的代码审查,代码中的幻数通常被认为是一个坏主意,而是写:
if (*s >= 'A' && *s <= 'Z')
甚至更好
if (isupper((unsigned int) *s))
不对ASCII上的依赖进行硬编码。
更新哦,正如评论中指出的那样,您无法更改 s
的值,然后将更改后的值传递给free()
,这也是未定义的行为。传递给free()
的地址必须与您从malloc()
返回的地址相同。
为迭代使用单独的变量:
char *p = s;
且仅free()
原始s
。
答案 1 :(得分:1)
首先,通过s=(char*)malloc(sizeof(char));
,您只为缓冲区分配1个字节的内存。分配足够的内存来存储输入。还要避免类型转换malloc()
结果。更好的版本看起来像
s = malloc(MAX * sizeof(*s));/* MAX is num of bytes you need to define */
其次,请勿使用gets()
使用fgets()
。阅读man 3 gets
或查看https://linux.die.net/man/3/gets
最后使用int main(void) { }
而不是main(){ }
当你执行free(s)
s
时,s++
更加重要而不是指向因s
而早先分配给它的内存,因此可能会导致错误,如
free():指针无效:
因此,在迭代时不要更改s[row]
使用s
或者您可以将free(s)
分配给其他指针,然后您可以执行int main() {
char *s = NULL;
int size = MAX*sizeof(*s);/*define MAX value, it is no of bytes need*/
s = malloc(size);/* this is generic
sizeof(*s) works for any data type */
printf("Enter a string:\n");
fgets(s,size,stdin);/* use fgets() instead of gets() */
int row = 0;
while (s[row]!='\0') {
if ( *(s+row) >= 65 && *(s+row) <= 90)
printf("%c",*(s+row) + 32);
else if( *(s+row) >=97 && *(s+row) <= 122)
printf("%c",*(s+row) - 32);
else
printf("%c",*(s+row));
row++;
}
free(s);/* s still points to same location */
return 0;
}
。
完整代码
isupper()
此外,您可以使用mkfifo my_named_pipe
而不是比较每个char ASCII值。
答案 2 :(得分:0)
这是错误的。
s = (char*)malloc(sizeof(char));
printf("Enter a string:\n");
gets(s);
s = (char*)malloc(sizeof(char));
分配1个字节的内存。然后用
gets(s);
你得到一个字符串,它将是Undefined Behavior。
您必须将其更改为
s = malloc(MAX_LENGTH * sizeof(char)); //MAX_LENGTH is user defined
此外,您必须检查malloc()
是否返回任何内容。如果它返回NULL
,则表示没有分配内存,并且所有现有程序都将调用未定义的行为。
此外,无需转换malloc
结果,因此为了进一步改进您的代码,您需要将其更改为,
s = malloc(MAX_LENGTH * sizeof(char));
if(s == NULL)
{
// Add error handling here
}
此外,
void main()
不再符合标准,请参阅This post解释原因。如果您想知道C11标准对此有何规定,请参考此处的标准:Section 5.1.2.2.1 Program startup
所以改成它,
int main(void)
您应确保仅在分配free(s);
时才调用free(NULL);
。正如下面的评论之一正确地指出s
不是问题,但它也没有效果,所以为什么还要调用它。
让NULL
再次指向 SELECT
DB.OrganisationPersonnel.OrganisationID
, DB.OrganisationPersonnel.PersonnelID AS [if not ProductPAID =5]
, DB.Title.Name
, DB.Person.FirstName
, DB.Person.MiddleName
, DB.Person.LastName
, DB.OrganisationPersonnel.ActualJobTitle
, DB.Phone.Number AS [if ProductPAID <3]
, DB.Email.Email AS [if ProductPAID =2 or 5]
, DB.Person.ProductDPAID
, DB.ProductDPA.Name
FROM
(((DB.OrganisationPersonnel
INNER JOIN
(DB.Person
INNER JOIN
DB.Title
ON
DB.Person.TitleID = DB.Title.ID)
ON
DB.OrganisationPersonnel.PersonnelID = DB.Person.ID)
LEFT JOIN
DB.Phone
ON
DB.OrganisationPersonnel.PhoneID = DB.Phone.ID)
LEFT JOIN
DB.Email
ON
DB.OrganisationPersonnel.EmailID = DB.Email.ID)
INNER JOIN
DB.ProductDPA
ON
DB.Person.ProductDPAID = DB.ProductDPA.ID
WHERE
(((DB.OrganisationPersonnel.EmployedToDate) Is Null))
ORDER BY
DB.OrganisationPersonnel.OrganisationID;
,但在此段代码中无关紧要。