我正在编写一个C程序,它将确定一个给定的字符串是否是半字符串(由两个或更多回文串组成),虽然我的解决方案确实有效,但我一直收到Valgrind错误,这些错误对我来说没有任何意义。我对C和valgrind相当陌生,虽然我大致了解这些错误的含义,但我不知道它们如何应用到我的代码中。
下面是我的代码:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
// Function to check if a given string is a palindrome
int isPalindrome(char str[]) {
int len = strlen(str);
if (len == 1){return 0;}
int left = 0;
int right = len - 1;
while (right > left) {
if (str[left++] != str[right--]) {
return 0;
}
}
return 1;
}
bool is_semidrome(char *s) {
int len = strlen(s);
// If empty string, automatically not a semidrome
if(len == 0){return 0;}
// If palindrome, automatically a semidrome
if(isPalindrome(s)){return 1;}
// Initialize two arrays to check if a substring is a palindrome
char *palcheck, *palcheckrest;
for (int i = 1; i < len; i++){
// Go through the array until we find a char same as s[0] (potential palindrome)
if (s[0] == s[i]){
// make an array of the potential palindrome
palcheck = malloc((i+2)*sizeof(char));
palcheck = strncpy(palcheck, s, i+1);
palcheck[i+1] = '\0';
// if it is a palindrome, recursively check if the rest is a semidrome
if (isPalindrome(palcheck)){
// make a new substring with the rest of the string
palcheckrest = malloc((len - i)*sizeof(char));
for (int j = 0; j < (len - i - 1); j++){
palcheckrest[j] = s[j+i+1];
}
palcheckrest[len - i] = '\0';
// if it is a semidrome, return true
if (is_semidrome(palcheckrest)){
free(palcheck);
free(palcheckrest);
return true;}
else{
free(palcheck);
free(palcheckrest);
// if i is the ending index and we still haven't found a potential palindrome, return false
if(i == len){
return false;}
// if i is not the ending index, keep checking
else{
free(palcheck);
free(palcheckrest);
continue;}
}}
else {
free(palcheck);
continue;}
}
}}
下面是valgrind的错误:
Input:
popeye==152438== Memcheck, a memory error detector
==152438== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==152438== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==152438== Command: ./student_answer
==152438==
==152438== Invalid write of size 1
==152438== at 0x10A3CE: is_semidrome (semidrome.c:39)
==152438== by 0x10A1EB: main (main.c:11)
==152438== Address 0x4a73154 is 0 bytes after a block of size 4 alloc'd
==152438== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==152438== by 0x10A377: is_semidrome (semidrome.c:35)
==152438== by 0x10A1EB: main (main.c:11)
==152438==
==152438== Conditional jump or move depends on uninitialised value(s)
==152438== at 0x483EF58: strlen (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==152438== by 0x10A2B4: is_semidrome (semidrome.c:23)
==152438== by 0x10A3DC: is_semidrome (semidrome.c:40)
==152438== by 0x10A1EB: main (main.c:11)
==152438==
==152438== Conditional jump or move depends on uninitialised value(s)
==152438== at 0x483EF58: strlen (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==152438== by 0x10A230: isPalindrome (semidrome.c:9)
==152438== by 0x10A2D3: is_semidrome (semidrome.c:25)
==152438== by 0x10A3DC: is_semidrome (semidrome.c:40)
==152438== by 0x10A1EB: main (main.c:11)
==152438==
==152438==
==152438== HEAP SUMMARY:
==152438== in use at exit: 0 bytes in 0 blocks
==152438== total heap usage: 5 allocs, 5 frees, 8,250 bytes allocated
==152438==
==152438== All heap blocks were freed -- no leaks are possible
==152438==
==152438== Use --track-origins=yes to see where uninitialised values come from
==152438== For lists of detected and suppressed errors, rerun with: -s
==152438== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
我知道我没有最有效或最优雅的解决方案,但目前的重点是了解如何修复Valgrind错误。
1条答案
按热度按时间7d7tgy0s1#
看看你的代码,Valgrind在告诉你你做错了什么.
“已分配大小为4的块.... is_semidrome(semidrome.c:35)”
因此,这就是您分配大小为4字节的内容的位置。
“大小为1的写入无效... is_semidrome(semidrome.c:39)”
这是你写的内存块的第5个字节。
您不能将5个字节写入4个字节的空间。
最有可能的解决方法是在第35行的分配大小上加1。