M
Modular2mo ago
Jake

List setItem vs append crashing?

Below I have two simple Matrix structs. They are the exact same except the lines called out by # <- comments. Why is the SetMatrix causing a crash while AppendMatrix is fine? (Run on https://docs.modular.com/mojo/playground for a quick repro)
struct AppendMatrix():
var value: List[List[Float64]]
var rows: Int
var cols: Int

fn __init__(out self, rows: Int, cols: Int):
self.rows = rows
self.cols = cols
self.value = List[List[Float64]](capacity = rows)
for i in range(rows):
self.value.append(List[Float64](capacity = cols)) # <- appending works fine
for j in range(cols):
self.value[i].append(10*i + j) # <- appending works fine

struct SetMatrix():
var value: List[List[Float64]]
var rows: Int
var cols: Int

fn __init__(out self, rows: Int, cols: Int):
self.rows = rows
self.cols = cols
self.value = List[List[Float64]](capacity = rows)
for i in range(rows):
self.value[i] = List[Float64](capacity = cols) # <- assigning causes a crash?
for j in range(cols):
self.value[i][j] = (10*i + j) # <- assigning is fine here

fn main():
print("Matrices!", flush = True)

for i in range(1, 10):
var A = AppendMatrix(i, 3)
print("A" + str(i), A.rows, "x", A.cols, flush = True)

for i in range(1, 10):
var B = SetMatrix(i, 3) # <- this will crash
print("B" + str(i), B.rows, "x", B.cols, flush = True)
struct AppendMatrix():
var value: List[List[Float64]]
var rows: Int
var cols: Int

fn __init__(out self, rows: Int, cols: Int):
self.rows = rows
self.cols = cols
self.value = List[List[Float64]](capacity = rows)
for i in range(rows):
self.value.append(List[Float64](capacity = cols)) # <- appending works fine
for j in range(cols):
self.value[i].append(10*i + j) # <- appending works fine

struct SetMatrix():
var value: List[List[Float64]]
var rows: Int
var cols: Int

fn __init__(out self, rows: Int, cols: Int):
self.rows = rows
self.cols = cols
self.value = List[List[Float64]](capacity = rows)
for i in range(rows):
self.value[i] = List[Float64](capacity = cols) # <- assigning causes a crash?
for j in range(cols):
self.value[i][j] = (10*i + j) # <- assigning is fine here

fn main():
print("Matrices!", flush = True)

for i in range(1, 10):
var A = AppendMatrix(i, 3)
print("A" + str(i), A.rows, "x", A.cols, flush = True)

for i in range(1, 10):
var B = SetMatrix(i, 3) # <- this will crash
print("B" + str(i), B.rows, "x", B.cols, flush = True)
3 Replies
eggsquad
eggsquad2mo ago
List(capacity=n) only allocates the memory but doesn't actually initialize it so it still has a size of 0 and indexing into those elements is an out of bounds access. If you want to bulk initialize a list you want List.resize
Jake
JakeOP2mo ago
And resize calls __copyinit__ for each entry? Is there a more performant way of just initializing space if you are going to set the values right after?
eggsquad
eggsquad2mo ago
I think the append based version is what you would want for something like this

Did you find this page helpful?